c36e2e6b91ff947b3d39a456e6bd028422f3c1c7
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
175 {
176 MODE_DEFAULT = 0,
177 MODE_NO_ZERORUNRESTART = 1,
178 MODE_NO_ZERORUN = 2
179 };
181 // syncState
182 enum
183 {
184 SYNC_NONE,
185 SYNC_ONE,
186 SYNC_ONGOING,
187 SYNC_PCM,
188 SYNC_PCM_FORCED,
189 SYNC_AUTO
190 };
192 // scanState
193 enum
194 {
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] =
215 {
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] =
243 {
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)
296 {
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)
311 {
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)
328 {
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)
344 {
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, srcFrame);
358 if (srcFrame->arg == PAF_SIO_REQUEST_AUTO) {
360 // if not yet running, prime input buffer
361 if (pDevExt->syncState == SYNC_NONE) {
363 status = DIB_FTABLE_reset (device, pBufConfig);
364 if (status)
365 return status;
367 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
369 status = DIB_FTABLE_issueChild (device, &pDevExt->bufConfig, pDevExt->autoRequestSize, 0);
370 if (status)
371 return status;
373 // * also reset pDevExt->zeroCount, as in DIB_getSync()?
374 // just for PAF_SOURCE_PCMAUTO? *
375 pDevExt->pcmTimeout =
376 pDevExt->sourceSelect == PAF_SOURCE_PCMAUTO ? 0 :
377 2 * pBufConfig->pBufStatus->unknownTimeout;
378 pDevExt->syncState = SYNC_AUTO;
380 // allows PCM decoder to be used to generate zero-valued audio frames while scanning
381 pBufConfig->deliverZeros = 1;
382 }
383 // no action if already sync'ed
384 else if (pDevExt->syncState != SYNC_AUTO)
385 return 0;
387 status = DIB_FTABLE_issueChild (device, &pDevExt->bufConfig, pDevExt->autoRequestSize, 0);
388 if (status)
389 return status;
390 }
391 else if (srcFrame->arg == PAF_SIO_REQUEST_NEWFRAME) {
393 // do nothing if not synced since syncing done in reclaim
394 // This is executed in force modes from the first call to PAF_AST_decodeInit
395 // which calls SIO2_issue for NEWFRAME before all other calls.
396 if (pDevExt->syncState == SYNC_NONE)
397 return 0;
399 status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
400 if (status)
401 return status;
402 }
404 return 0;
405 } // DIB_issue
407 // -----------------------------------------------------------------------------
408 // Although interface allows for arbitrary BufConfigs we only support 1 -- so
409 // we can assume the one on the fromdevice is the one we want
411 extern int gIsrCnt; // GJ Debug
413 Int DIB_reclaim (DEV2_Handle device)
414 {
415 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *) device->object;
416 DEV2_Frame *dstFrame;
417 Int status = 0;
418 PAF_InpBufConfig *pBufConfig;
420 dstFrame = (DEV2_Frame *) Queue_head (device->fromdevice);
422 if (dstFrame == (DEV2_Frame *) device->fromdevice)
423 return DIBERR_UNSPECIFIED;
424 if (!dstFrame->addr)
425 return DIBERR_UNSPECIFIED;
427 // if deferred error from last request frame then return now
428 status = pDevExt->deferredError;
429 if (status) {
430 pDevExt->deferredError = 0;
431 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
432 return status;
433 }
435 pBufConfig = (Ptr) dstFrame->addr;
436 dstFrame->size = sizeof (PAF_InpBufConfig);
438 // .........................................................................
440 if (dstFrame->arg == PAF_SIO_REQUEST_AUTO) {
442 Log_info0("DIB: At case = PAF_SIO_REQUEST_AUTO"); // GJ Debug
444 // verify set up by prior DIB_issue()
445 // no action if already sync'ed
446 if (pDevExt->syncState == SYNC_NONE)
447 return DIBERR_AUTO;
448 else if (pDevExt->syncState != SYNC_AUTO)
449 return 0;
451 // get next block of data to scan
452 status = DIB_FTABLE_waitForData (device, &pDevExt->bufConfig, pDevExt->autoRequestSize);
453 if (status)
454 return status;
456 if (pDevExt->sourceSelect == PAF_SOURCE_NONE) {
457 IncrementPtr (pBufConfig, &pDevExt->bufConfig.pntr.pVoid, pDevExt->autoRequestSize);
458 return 0;
459 }
461 // this function updates the tail pointer; it WON'T reset to SYNC_NONE
462 status = DIB_FTABLE_syncScan (device, &pDevExt->bufConfig, &pDevExt->pcmTimeout);
463 if (status)
464 return status;
466 // if not yet sync'ed ...
467 if (pDevExt->syncState == SYNC_AUTO) {
468 // if timeout, harness tail of DIB_getSync()
469 if (!pDevExt->pcmTimeout) {
471 // checks pDevExt->zeroCount, runs DIB_reset(),
472 // updates pBufConfig->deliverZeros/sizeofElement/sizeofBuffer,
473 // sets pDevExt->sourceProgram = PAF_SOURCE_PCM/DSD?
474 // and pDevExt->syncState = SYNC_PCM[_FORCED]
475 status = DIB_FTABLE_getSync (device, &pDevExt->bufConfig);
476 if (status)
477 return status;
478 }
479 }
481 // if sync'ed to bitstream, this requests add'l input;
482 // if PCM, this "kickstarts" the input,
483 // using settings per above call to DIB_getSync()
484 if (pDevExt->syncState != SYNC_AUTO) {
486 status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
487 if (status)
488 return status;
490 // this situation may occur for various IEC types,
491 // w/ no matching PAF_SOURCE_ type is defined
492 // (see iecPafSource[] table for the latter mapping)
493 // most like cases are null & pause packets
494 if (pDevExt->sourceProgram == PAF_SOURCE_UNKNOWN)
495 return DIBERR_SYNC;
497 // request timing frame
498 status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
499 if (status)
500 return status;
501 }
502 } //dstFrame->arg == PAF_SIO_REQUEST_AUTO
504 // .........................................................................
506 if ((pDevExt->syncState == SYNC_NONE) || (dstFrame->arg == PAF_SIO_REQUEST_SYNC)) {
508 Log_info0("DIB: At case: syncState == SYNC_NONE (or PAF_SIO_REQUEST_SYNC)"); // GJ Debug
510 // pass in external buffer config which used to initialize the internal view
511 status = DIB_FTABLE_reset (device, pBufConfig);
512 if (status)
513 return status;
515 status = DIB_FTABLE_getSync (device, &pDevExt->bufConfig);
516 if (status)
517 return status;
519 // since getSync resets sourceProgram to unknown at entry
520 // sourceProgram will remain unknown if no sync is returned
521 // (i.e. no need to reset it here)
522 if (pDevExt->syncState == SYNC_NONE)
523 {
524 Log_info0("Returning DIBERR_SYNC after DIB_FTABLE_getSync"); // GJ Debug
525 return DIBERR_SYNC;
526 }
528 // get input info (frameLength/etc)
529 status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
531 if (status)
532 {
533 Log_info1("Returning %d after DIB_FTABLE_initFrame", status); // GJ Debug
534 return status;
535 }
537 // request timing frame
538 status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
539 if (status)
540 {
541 Log_info1("Returning %d after DIB_FTABLE_requestFrame", status); // GJ Debug
542 return status;
543 }
544 // update external view of bufConfig. In particular for slave force PCM
545 // this insures that the first decode will be processed with deliverZeros = 1
546 // which is necessary since the first decode of slave input occurs before the
547 // first slave input frame is actually captured.
548 *pBufConfig = pDevExt->bufConfig;
550 } //((pDevExt->syncState == SYNC_NONE) || (dstFrame->arg == PAF_SIO_REQUEST_SYNC))
552 // .........................................................................
554 if (dstFrame->arg == PAF_SIO_REQUEST_NEWFRAME) {
556 Log_info0("DIB: At case = PAF_SIO_REQUEST_NEWFRAME"); // GJ Debug
558 // wait for enough data to check for sync at expected location
559 status = DIB_FTABLE_waitForData (device, &pDevExt->bufConfig, pDevExt->bufConfig.frameLength);
560 if (status)
561 {
562 Log_info2("DIB_reclaim.%d DIB_FTABLE_waitForData returned %d", __LINE__, status); // GJ Debug
563 //TRACE((&TR_MOD, "DIB_reclaim.%d DIB_FTABLE_waitForData returned %d\n", __LINE__, status));
564 return status;
565 }
567 // if PCM, but not forced PCM, then scan for bitstream sync
568 // note that we we using the local view of bufConfig here and we update the
569 // public view afterwards.
570 if (pDevExt->syncState == SYNC_PCM) {
571 float sampleRate = PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD];
572 PAF_InpBufConfig *pBufConfig = &pDevExt->bufConfig;
573 Int ibMode = pBufConfig->pBufStatus->mode; // read mode register once
575 // normally no scanning done if sampleRate > 48kHz since bitstream input is highly unlikley.
576 if ((sampleRate <= SCANATSAMPLERATELIMIT) || pBufConfig->pBufStatus->scanAtHighSampleRateMode) {
577 if (!pBufConfig->deliverZeros) {
578 pDevExt->pcmTimeout = pBufConfig->lengthofData;
580 // check zeroRunTrigger if needed
581 if (ibMode != MODE_NO_ZERORUN) {
582 if(pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger) {
583 // set this flag one block late to allow for
584 // transmission of all data in frame which contained zeroRunTrigger
585 pBufConfig->deliverZeros = 1;
586 pDevExt->pcmTimeout = 2 * pBufConfig->pBufStatus->unknownTimeout;
587 } // > zeroRunTrigger
588 } // !MODE_NO_ZERORUN
589 } // !pBufConfig->deliverZeros
591 // scan PCM data
592 status = DIB_FTABLE_syncScan (device, pBufConfig, &pDevExt->pcmTimeout);
593 if (status) {
594 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
595 Log_info2("DIB_reclaim.%d DIB_FTABLE_syncScan returned %d", __LINE__, status); // GJ Debug
596 //TRACE((&TR_MOD, "DIB_reclaim.%d DIB_FTABLE_syncScan returned %d\n", __LINE__, status));
597 return status;
598 }
600 // if scan found something other than PCM, then exit with error
601 if (pDevExt->syncState != SYNC_PCM)
602 {
603 Log_info1("DIB_reclaim.%d error: syncState != SYNC_PCM", __LINE__); // GJ Debug
604 //TRACE((&TR_MOD, "DIB_reclaim.%d error: syncState != SYNC_PCM\n", __LINE__));
605 return DIBERR_SYNC;
606 }
608 // if heeding zeroRunRestart control then return to unknown if necessary
609 if ((ibMode == MODE_DEFAULT) &&
610 (pDevExt->zeroCount >= 2*pBufConfig->pBufStatus->zeroRunRestart)) {
611 // if zeroRunRestart me then reset input to unknown
612 Log_info1("DIB_reclaim.%d error: zeroRunRestart, setting PAF_SOURCE_UNKNOWN", __LINE__); // GJ Debug
613 //TRACE((&TR_MOD, "DIB_reclaim.%d error: zeroRunRestart, setting PAF_SOURCE_UNKNOWN\n", __LINE__));
614 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
615 return DIBERR_SYNC;
616 }
618 // since in skeptical state we disallow returning to PCM when end of timeout contains zeros
619 // note that we need not check the mode here since above logic prevents deliverZeros state.
620 if (pBufConfig->deliverZeros && (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger))
621 {
622 //TRACE((&TR_MOD, "DIB_reclaim.%d set pcmTimeout = unknown timeout\n", __LINE__));
623 pDevExt->pcmTimeout = 2 * pBufConfig->pBufStatus->unknownTimeout;
624 }
625 } //scanAtHighSampleRate
626 } //SYNC_PCM
628 // clear this flag immediately to play new audio ASAP
629 // this check is OK for forced PCM since pcmTimeout and zeroCount are not
630 // updated
631 if (pDevExt->bufConfig.deliverZeros && !pDevExt->pcmTimeout &&
632 (pDevExt->zeroCount < 2 * pDevExt->bufConfig.pBufStatus->zeroRunTrigger))
633 {
634 pDevExt->bufConfig.deliverZeros = 0;
635 }
637 // update external view of buffer with local view we do this with current
638 // frame info before the following update to the local view for the next
639 // frame to be captured. Need to subtract headerSize from lengthofData
640 // since, at least for THD, it is needed by decoders.
641 *pBufConfig = pDevExt->bufConfig;
642 pBufConfig->lengthofData -= pDevExt->headerSize;
643 Log_info3("DIB_reclaim.%d lengthofData = %d; ISRCNT=%d", __LINE__, pBufConfig->lengthofData, gIsrCnt); // GJ Debug
644 //TRACE((&TR_MOD, "DIB_reclaim.%d lengthofData = %d\n", __LINE__, pBufConfig->lengthofData));
646 // HACK: for DSD the frameLength needs to be the number of samples to generate.
647 if ((pDevExt->sourceSelect >= PAF_SOURCE_DSD1) &&
648 (pDevExt->sourceSelect <= PAF_SOURCE_DSD3))
649 pBufConfig->frameLength /= pBufConfig->stride;
650 Log_info2("DIB_reclaim.%d frameLength = %d", __LINE__, pBufConfig->frameLength); // GJ Debug
651 //TRACE((&TR_MOD, "DIB_reclaim.%d frameLength = %d\n", __LINE__, pBufConfig->frameLength));
653 // set external view to point at synch position of the frame guaranteed
654 // to be captured by above waitForData. Need to condition this against PCM since
655 // in that case pSync could point anywhere in the buffer to to syncScan. E.g.
656 // if there was a partial sync then pSync would point at that rather than
657 // at the beginning of the buffer.
658 // TODO: change syncScan to only update pDevExt->pSync when there is an actual sync
659 // so that we can use this for both PCM and bitstream
660 if (pDevExt->syncState == SYNC_ONGOING) {
661 pBufConfig->pntr = pDevExt->pSync;
662 IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pDevExt->headerSize);
663 } //SYNC_ONGOING
665 // if a bitstream then need to update tail to bitstream sync location
666 // and check for next sync at expected location
667 // quick scan for sync. if decoding IEC but sync is missing then
668 // defer error until the next frame so that we decode all frames
669 // TODO: does this assume decoders have copied the entire input frame
670 // i.e. it is ok to adjust the input buffer pointers.
671 // if successful then this sets
672 // pSync = address of PA (for IEC)
673 status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
674 if (status) {
675 if (pBufConfig->pBufStatus->lastFrameMask & (1 << pDevExt->sourceProgram)) {
676 pDevExt->deferredError = status;
677 Log_info1("DIB_reclaim.%d last frame\n", __LINE__); // GJ Debug
678 //TRACE((&TR_MOD, "DIB_reclaim.%d last frame\n", __LINE__));
679 pBufConfig->pBufStatus->lastFrameFlag = 1;
680 return 0;
681 }
682 else {
683 Log_info1("DIB_reclaim.%d setting PAF_SOURCE_UNKNOWN", __LINE__); // GJ Debug
684 //TRACE((&TR_MOD, "DIB_reclaim.%d setting PAF_SOURCE_UNKNOWN\n", __LINE__));
685 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
686 return status;
687 }
688 }
690 } //(dstFrame->arg == PAF_SIO_REQUEST_NEWFRAME)
692 // .........................................................................
694 Log_info3("DIB_reclaim.%d exit status = %d, ISRCNT = %d", __LINE__, status, gIsrCnt); // GJ Debug
695 //TRACE((&TR_MOD, "DIB_reclaim.%d exit status = %d\n", __LINE__, status));
697 return status;
698 } // DIB_reclaim
700 // -----------------------------------------------------------------------------
702 Int DIB_ctrl (DEV2_Handle device, Uns code, Arg arg)
703 {
704 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
705 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
706 Int status = 0;
709 switch (code) {
711 case PAF_SIO_CONTROL_GET_CHILD_DEVICE:
712 *((Arg *)arg) = (Arg) pChild;
713 break;
715 //,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
717 case PAF_SIO_CONTROL_SET_DECSTATUSADDR:
718 pDevExt->pDecodeStatus = (PAF_DecodeStatus *) arg;
719 break;
721 case PAF_SIO_CONTROL_SET_PCMFRAMELENGTH:
722 pDevExt->pcmFrameLength = (XDAS_Int32) arg;
723 break;
725 case PAF_SIO_CONTROL_SET_SOURCESELECT:
726 pDevExt->sourceSelect = (XDAS_Int8) arg;
727 break;
729 case PAF_SIO_CONTROL_SET_AUTOREQUESTSIZE:
730 pDevExt->autoRequestSize = (XDAS_Int16) arg;
731 break;
733 case PAF_SIO_CONTROL_GET_SOURCEPROGRAM:
734 if (!arg)
735 return DIBERR_UNSPECIFIED;
736 *((XDAS_Int8 *) arg) = pDevExt->sourceProgram;
737 break;
739 case PAF_SIO_CONTROL_SET_IALGADDR:
740 pDevExt->pSioIalg = (PAF_SIO_IALG_Obj *) arg;
741 break;
743 //,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
745 case PAF_SIO_CONTROL_OPEN:
746 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
747 pDevExt->zeroCount = 0;
748 if (pDevExt->pInpBufStatus)
749 pDevExt->pInpBufStatus->zeroRun = 0;
750 status = DEV2_ctrl (pChild, code, arg);
751 break;
753 case PAF_SIO_CONTROL_CLOSE:
754 if (pDevExt->pInpBufStatus)
755 pDevExt->pInpBufStatus->zeroRun = 0;
756 status = DEV2_ctrl (pChild, code, arg);
757 break;
759 // return number of DMA events vs. request size
760 // only update if not in error state (i.e. status = 0)
761 case PAF_SIO_CONTROL_GET_NUM_EVENTS:
762 if (!arg)
763 return DIBERR_UNSPECIFIED;
764 status = DEV2_ctrl (pChild, code, arg);
765 if (!status)
766 *((Int *)arg) -= pDevExt->pcmFrameLength;
767 break;
769 // return net samples until next DIB_waitForData() should succeed w/o blocking
770 case PAF_SIO_CONTROL_GET_NUM_REMAINING:
771 if (!arg)
772 return DIBERR_UNSPECIFIED;
773 status = DEV2_ctrl (pChild, code, arg);
774 *((Int *)arg) -= pDevExt->numSamplesExtra;
775 break;
777 default:
778 status = DEV2_ctrl (pChild, code, arg);
779 break;
780 }
782 return status;
783 } // DIB_ctrl
785 // -----------------------------------------------------------------------------
787 Int DIB_idle (DEV2_Handle device, Bool flush)
788 {
789 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
790 Int status;
793 while (!Queue_empty (device->todevice))
794 Queue_enqueue (device->fromdevice, Queue_dequeue (device->todevice));
796 while (!Queue_empty (device->fromdevice))
797 Queue_enqueue (&((SIO2_Handle) device)->framelist, Queue_dequeue (device->fromdevice));
799 status = DIB_FTABLE_reset (device, NULL);
800 if (status)
801 return status;
803 return 0;
804 } // DIB_idle
806 // -----------------------------------------------------------------------------
808 Int DIB_open (DEV2_Handle device, String name)
809 {
810 DIB_DeviceExtension *pDevExt;
811 DEV2_Handle pChild;
812 DEV2_Device *entry;
813 DEV2_Frame *frame;
814 Int status, i;
815 Error_Block eb;
817 Error_init(&eb);
819 name = DEV2_match (name, &entry);
820 if (entry == NULL) {
821 Log_info1("DEV2_match failed in DIB_open:", SIO2_ENODEV);
822 return SIO2_ENODEV;
823 }
825 // only one frame interface supported
826 if (device->nbufs != 1)
827 return SYS_EALLOC;
829 if (!(pDevExt = Memory_alloc (device->bufSeg, sizeof(DIB_DeviceExtension), 0, &eb)))
830 {
831 Log_info1("DIB Memory alloc failed in DIB_open:", SYS_EALLOC);
832 return SYS_EALLOC;
833 }
834 pDevExt->pcmFrameLength = 0;
835 pDevExt->sourceSelect = PAF_SOURCE_NONE;
836 pDevExt->autoRequestSize = DEFAULT_AUTOREQUESTSIZE;
837 pDevExt->pInpBufStatus = NULL;
838 pDevExt->pDecodeStatus = NULL;
839 device->object = (Ptr)pDevExt;
841 pChild = (DEV2_Handle)&pDevExt->child;
842 pChild->fromdevice = Queue_create (NULL, &eb);
843 pChild->todevice = Queue_create (NULL, &eb);
844 if (pChild->fromdevice == NULL || pChild->todevice == NULL) {
845 Log_info1 ("DIB Queue_create failed in DIB_open:", SYS_EALLOC);
846 return SYS_EALLOC;
847 }
849 pChild->bufsize = 0;
850 pChild->nbufs = NUM_CHILD_BUFFERS;
851 pChild->bufSeg = device->bufSeg;
852 pChild->mode = device->mode;
853 pChild->timeout = device->timeout;
854 pChild->align = device->align;
855 pChild->devid = entry->devid;
856 pChild->params = entry->params;
857 pChild->fxns = *(DEV2_Fxns *)(entry->fxns);
858 ((SIO2_Handle)pChild)->model = ((SIO2_Handle)device)->model;
860 //Create frames and put them on the correct device queue.
861 // We only support ISSUERECLAIM mode so size = 0
862 Queue_construct(&((SIO2_Handle)pChild)->framelist, NULL); //Queue_new (&((SIO2_Handle)pChild)->framelist);
863 for (i=0; i < pChild->nbufs; i++) {
864 frame = DEV2_mkframe (0, 0, 0);
865 if (!frame)
866 return SYS_EALLOC;
867 Queue_put (&((SIO2_Handle)pChild)->framelist, frame);
868 }
870 // open underlying device
871 status = DEV2_open (pChild, name);
872 if (status)
873 return status;
875 // use dev match to fetch function table pointer for DIB
876 name = DEV2_match ("/DIB", &entry);
877 if (entry == NULL) {
878 Log_info1 ("DEV2_match for DIB in DIB_open:", SIO2_ENODEV);
879 return SIO2_ENODEV;
880 }
881 pDevExt->pFxns = (DIB_Fxns *) entry->fxns;
883 // set IEC frame length table pointer -- change in
884 // subsequent control call (not defined) to add new IEC type
885 pDevExt->pIECFrameLength = (XDAS_UInt16 *) iecFrameLength;
887 status = DIB_FTABLE_reset (device,NULL);
888 if (status)
889 return status;
891 return status;
892 } // DIB_open
894 // -----------------------------------------------------------------------------
895 // Although this is void it is still needed since BIOS calls all DEV inits on
896 // startup.
898 Void DIB_init (Void)
899 {
900 } // DIB_init
902 // -----------------------------------------------------------------------------
903 // Notes:
904 // 1. DIB_reset is called prior to this function being called.(see DIB_reclaim)
905 // 2. (1) ==> sizeofBuffer is an integral # of 2byte samples.
906 // 3. (2) ==> if we use a request size which is divisor of sizeofBuffer there
907 // will be no wrap-around when requesting data for scanning.
908 // 4. (3) ==> we meet the interface requirement for syncScan which has no
909 // circular arithmetic.
911 Int DIB_getSync (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
912 {
913 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
914 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
915 int status;
916 Uns timeout, syncBufSize, syncRequestSize;
917 Int ibMode = pBufConfig->pBufStatus->mode; // read mode register once
918 Int deliverZeros;
920 //..........................................................................
922 // implement local timeout so that we don't get 'stuck' here when input
923 // is all zeros + lock
924 if (pDevExt->syncState == SYNC_NONE) {
925 Uns localTimeout;
926 // latch value before resetting to PAF_SOURCE_UNKNOWN
927 Int sourceProgram = pDevExt->sourceProgram;
929 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
931 // if here then guaranteed to have fresh reset
933 if (pDevExt->sourceSelect == PAF_SOURCE_PCM || pDevExt->sourceSelect == PAF_SOURCE_DSD1 ||
934 pDevExt->sourceSelect == PAF_SOURCE_DSD2 || pDevExt->sourceSelect == PAF_SOURCE_DSD3) {
935 timeout = 0;
937 // no zero run counting in force modes since no scanning
938 pBufConfig->pBufStatus->zeroRun = 0;
939 pDevExt->zeroCount = 0;
940 }
941 else if ((pDevExt->sourceSelect == PAF_SOURCE_PCMAUTO) &&
942 ((sourceProgram == PAF_SOURCE_UNKNOWN) || (sourceProgram == PAF_SOURCE_PCM))) {
943 // if sourceselect is PCMAUTO then
944 // if current input is a bistream then scan for normal timeout period
945 // if current input is unknown or PCM then transition immediately to PCM
946 // this provides for *no* lossed PCM, detection of bitstreams, but some noise
947 // is possible.
948 timeout = 0;
949 pDevExt->zeroCount = 0;
950 }
951 else
952 timeout = 2*pBufConfig->pBufStatus->unknownTimeout;
954 // force request size to be a divisor of sizeofBuffer
955 syncRequestSize = NOMINAL_XFERSIZE;
956 if (pBufConfig->stride > 2)
957 syncRequestSize *= pBufConfig->stride;
958 syncBufSize = pBufConfig->sizeofBuffer / ((int) (pBufConfig->sizeofBuffer/syncRequestSize));
960 if (timeout) {
961 status = DIB_FTABLE_issueChild (device, pBufConfig, syncBufSize, 0);
962 if (status)
963 return status;
964 }
966 localTimeout = timeout;
967 while ((timeout) && (pDevExt->syncState != SYNC_ONE)) {
969 status = DIB_FTABLE_issueChild (device, pBufConfig, syncBufSize, 0);
970 if (status)
971 return status;
973 // get next block of data to scan
974 status = DIB_FTABLE_waitForData (device, pBufConfig, syncBufSize);
975 if (status)
976 return status;
978 // this function updates the tail pointer
979 status = DIB_FTABLE_syncScan (device, pBufConfig, &timeout);
980 if (status)
981 return status;
983 // if input is zero, i.e. haven't decremented at all,
984 // then break out and use more logic and
985 if (localTimeout < syncBufSize) {
986 // Should this be 2 *? MAW
987 if (timeout == 2*pBufConfig->pBufStatus->unknownTimeout)
988 break;
989 }
990 else
991 {
992 Log_info3("DIB: Inside DIB_getSync with syncState != SYNC_ONE. localTimeout = %d, syncBufSize = %d, timeout = %d", localTimeout,syncBufSize, timeout); // GJ Debug
993 localTimeout -= syncBufSize;
994 }
995 }
997 // if found sync then return to caller who will call
998 // initFrame to get bitstream info and requestFrame for data
999 if (pDevExt->syncState != SYNC_NONE)
1000 return 0;
1002 } //pDevExt->syncState == SYNC_NONE
1004 //..........................................................................
1006 // set default to zero -- we assume decode calls will not be made
1007 // before data is available since this must be master input. Will be changed below
1008 // as needed
1009 deliverZeros = 0;
1011 if (pDevExt->syncState == SYNC_AUTO) {
1012 timeout = pDevExt->pcmTimeout;
1013 deliverZeros = 1;
1014 }
1016 // if in zero run, and heeding full zeroRun control, then return to unknown if # zeros > trigger/Restart
1017 if (ibMode == MODE_DEFAULT) {
1018 if ((pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger) ||
1019 (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunRestart))
1020 return DIBERR_SYNC;
1021 // since we may have exited prematurely above we check timeout
1022 if (timeout)
1023 return DIBERR_SYNC;
1024 }
1025 // if heeding trigger but not restart then enter deliverZeros state of PCM
1026 else if (ibMode == MODE_NO_ZERORUNRESTART) {
1027 if (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger)
1028 deliverZeros = 1;
1029 }
1031 // here if timeout to PCM (includes force PCM)
1032 status = DIB_FTABLE_reset (device, pBufConfig);
1033 if (status)
1034 return status;
1036 // hack -- try 32bit then 16bit if necessary
1037 pBufConfig->sizeofElement = 4;
1038 status = SIO2_ctrl (pChild,(Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1039 if(status) {
1040 pBufConfig->sizeofElement = 2;
1041 status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1042 if(status)
1043 return status;
1044 }
1046 // Force sizeofBuffer to be integral number of frame sizes. This ensures that the
1047 // pcm buffers will not need a circular wrap-around. We prevent this because
1048 // syncScan makes this assumption in order to perform an efficient scan.
1049 {
1050 int sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride*pDevExt->pcmFrameLength;
1051 pBufConfig->sizeofBuffer = pBufConfig->allocation/sizeofStride*sizeofStride;
1052 }
1054 if (pDevExt->sourceSelect == PAF_SOURCE_DSD1 || pDevExt->sourceSelect == PAF_SOURCE_DSD2 ||
1055 pDevExt->sourceSelect == PAF_SOURCE_DSD3)
1056 pDevExt->sourceProgram = pDevExt->sourceSelect;
1057 else
1058 pDevExt->sourceProgram = PAF_SOURCE_PCM;
1060 if (pDevExt->sourceSelect == PAF_SOURCE_PCM || pDevExt->sourceSelect == PAF_SOURCE_DSD1 ||
1061 pDevExt->sourceSelect == PAF_SOURCE_DSD2 || pDevExt->sourceSelect == PAF_SOURCE_DSD3) {
1062 pDevExt->syncState = SYNC_PCM_FORCED;
1063 // set to one -- ensures that PCM decode calls made before data is
1064 // available will result in zero output.
1065 // (mostly needed for PA15 since, currently, all other frameworks
1066 // require a frame of data before the first decode call.
1067 deliverZeros = 1;
1068 }
1069 else
1070 pDevExt->syncState = SYNC_PCM;
1072 // update config struct
1073 pBufConfig->deliverZeros = deliverZeros;
1075 //..........................................................................
1077 return 0;
1078 } // DIB_getSync
1080 // -----------------------------------------------------------------------------
1082 Int DIB_issueChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, int size, int forTotal)
1083 {
1084 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *) device->object;
1085 DEV2_Handle pChild = (DEV2_Handle) &pDevExt->child;
1086 int bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1087 DEV2_Frame *dstFrame;
1088 int futureHead, status;
1089 int i, sizes[2];
1090 Ptr endAddr[2];
1094 // if seeking for total amount then adjust for difference
1095 if (forTotal)
1096 size -= GetFutureAvail (pBufConfig);
1098 // return success if we needn't make any requests
1099 if (size <= 0)
1100 return 0;
1102 // assume if eight channel then using optimized dMAX routine which requires
1103 // requests which are a mulitple of 8 to operate correctly. If not a proper
1104 // multiple then we increase the requested size as needed. This information
1105 // is communicated to other portions of DIB indirectly through the update
1106 // of the futureHead pointer (here) and head pointer (in reclaim). To these
1107 // other portions it is a don't care as we ensure enough data requested will
1108 // be available at, the now slightly deferred, reclaim point. We assume that
1109 // the buffer is a multiple of 8 and so, by using this single statement, we
1110 // ensure all requests are a mulitple 8 even if they need to be split across
1111 // the buffer wrap point.
1112 if (pBufConfig->stride == 8)
1113 size = (size + 7) & ~0x7;
1115 // convert to bytes
1116 size = (size * pBufConfig->sizeofElement); //To Do: +2 GJ : Temporary, to get past initial hiccup. // GJ Debug
1117 //size *= 4;
1119 // if request crosses circular buffer boundary then split into two requests
1120 futureHead = (int) pBufConfig->futureHead.pVoid + size;
1121 if (futureHead <= bufEnd) {
1122 sizes[0] = size;
1123 sizes[1] = 0;
1125 // If this request happens to be the rest of the buffer, then
1126 // futureHead must be set to the beginning of the buffer.
1127 if (futureHead != bufEnd)
1128 endAddr[0] = (Ptr) futureHead;
1129 else
1130 endAddr[0] = pBufConfig->base.pVoid;
1131 }
1132 else {
1133 sizes[0] = bufEnd - (int) pBufConfig->futureHead.pVoid;
1134 sizes[1] = futureHead - bufEnd;
1135 endAddr[0] = pBufConfig->base.pVoid;
1136 endAddr[1] = (Ptr) ((int)pBufConfig->base.pVoid + sizes[1]);
1137 }
1139 for (i=0; i < 2; i++) {
1140 if (sizes[i]) {
1141 dstFrame = Queue_get (&((SIO2_Handle) pChild)->framelist);
1142 if (dstFrame == (DEV2_Frame *)&((SIO2_Handle) pChild)->framelist)
1143 return DIBERR_UNSPECIFIED;
1144 dstFrame->arg = (Arg) pBufConfig;
1146 dstFrame->addr = pBufConfig->futureHead.pVoid;
1147 dstFrame->size = sizes[i];
1148 Queue_put (pChild->todevice, dstFrame);
1149 status = DEV2_issue (pChild);
1150 if (status)
1151 return DIBERR_UNSPECIFIED;
1153 pBufConfig->futureHead.pVoid = endAddr[i];
1154 }
1155 }
1157 return 0;
1158 } // DIB_issueChild
1160 // -----------------------------------------------------------------------------
1162 Int DIB_reclaimChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1163 {
1164 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1165 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
1166 DEV2_Frame *srcFrame;
1167 int status, bufEnd;
1169 //Log_info3("DIB_reclaimChild.%d: Inside DEV2_reclaim(pChild) pChild = 0x%x DEV2_reclaim = 0x%x", __LINE__, pChild, &pChild->fxns.reclaim); // GJ Debug
1170 //TRACE((&TR_MOD, "DIB_reclaimChild.%d: calling DEV2_reclaim(pChild) pChild = 0x%x DEV2_reclaim = 0x%x", __LINE__, pChild, &pChild->fxns.reclaim));
1171 status = DEV2_reclaim (pChild);
1172 if (status)
1173 {
1174 Log_info2("DIB_reclaimChild.%d DEV2_reclaim() returned (%d) DIBERR_UNSPECIFIED", __LINE__, status); // GJ Debug
1175 //TRACE((&TR_MOD, "DIB_reclaimChild.%d DEV2_reclaim() returned (%d) DIBERR_UNSPECIFIED \n", __LINE__, status));
1176 return DIBERR_UNSPECIFIED;
1177 }
1179 //Log_info1("DIB_reclaimChild.%d calling Queue_get()", __LINE__); // GJ Debug
1180 //TRACE((&TR_MOD, "DIB_reclaimChild.%d calling Queue_get()\n", __LINE__));
1181 srcFrame = Queue_get (pChild->fromdevice);
1182 //Log_info2("DIB_reclaimChild.%d calling Queue_put(), srcFrame = 0x%x", __LINE__, srcFrame); // GJ Debug
1183 //TRACE((&TR_MOD, "DIB_reclaimChild.%d calling Queue_put(), srcFrame = 0x%x\n", __LINE__, srcFrame));
1184 Queue_put (&((SIO2_Handle) pChild)->framelist, srcFrame);
1186 // Only for non-fill requests do we update ptrs
1187 if (srcFrame->addr != NULL) {
1188 //Log_info2("DIB_reclaimChild.%d update pointers with srcFrame->size = %d", __LINE__, srcFrame->size); // GJ Debug
1189 //TRACE((&TR_MOD, "DIB_reclaimChild.%d update pointers\n", __LINE__));
1190 pBufConfig->head.pVoid = (Ptr) ((int)srcFrame->addr + srcFrame->size);
1192 // wrap, if necessary
1193 bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1194 if( (int) pBufConfig->head.pVoid >= bufEnd )
1195 {
1196 Log_info1("DIB_reclaimChild.%d wrap pointer", __LINE__); // GJ Debug
1197 //TRACE((&TR_MOD, "DIB_reclaimChild.%d wrap pointer\n", __LINE__));
1198 pBufConfig->head.pVoid = (Ptr) ((int) pBufConfig->base.pVoid + (int) pBufConfig->head.pVoid - bufEnd);
1199 }
1200 }
1202 Log_info2("DIB_reclaimChild.%d exit with status = %d", __LINE__, status); // GJ Debug
1203 //TRACE((&TR_MOD, "DIB_reclaimChild.%d exit with status = %d\n", __LINE__, status));
1205 return status;
1206 } // DIB_reclaimChild
1208 // -----------------------------------------------------------------------------
1209 // This function uses the local definition of frameLength and lengthofData in
1210 // pDevExt to request the next frame of data.
1212 Int DIB_requestFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1213 {
1214 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1215 int status = 0;
1218 // if in steady state then update tail pointer to indicate we are done, i.e. no
1219 // longer own, the last frame of data.
1220 if (pDevExt->running > 1)
1221 IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pBufConfig->lengthofData);
1223 switch (pDevExt->syncState) {
1224 case SYNC_PCM:
1225 case SYNC_PCM_FORCED:
1227 if (pDevExt->sourceSelect == PAF_SOURCE_DSD1)
1228 pDevExt->frameLength = 256;
1229 else if (pDevExt->sourceSelect == PAF_SOURCE_DSD2)
1230 pDevExt->frameLength = 128;
1231 else if (pDevExt->sourceSelect == PAF_SOURCE_DSD3)
1232 pDevExt->frameLength = 64;
1233 else
1234 pDevExt->frameLength = pDevExt->pcmFrameLength;
1236 pDevExt->lengthofData = pBufConfig->stride*pDevExt->frameLength;
1237 pDevExt->frameLength = pDevExt->lengthofData;
1239 // note that the following issueChild
1240 // doesn't *fetch* the data which will next be consumed,
1241 // but rather *replenishes* what's about to be consumed
1242 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1243 break;
1245 case SYNC_ONE:
1246 // for the first issue we need to set the tail pointer to the bitstream sync
1247 pBufConfig->pntr = pDevExt->pSync;
1248 IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pDevExt->headerSize);
1249 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->frameLength, 1);
1251 // HD codecs need extra time due to several factors
1252 // time between first info call and starting output is non-negligible
1253 // peak decoder MIPs
1254 // reset time for decoders/ASPs
1255 if ((pDevExt->sourceProgram == PAF_SOURCE_DDP) ||
1256 (pDevExt->sourceProgram == PAF_SOURCE_DTSHD) ||
1257 (pDevExt->sourceProgram == PAF_SOURCE_THD) ||
1258 (pDevExt->sourceProgram == PAF_SOURCE_DXP))
1259 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1261 pDevExt->syncState = SYNC_ONGOING;
1262 break;
1264 case SYNC_ONGOING:
1265 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1266 break;
1268 } //switch
1270 // update bufConfig with info for use in next reclaim call
1271 // the interface to DIB is based on a single frame. So the amount
1272 // of data requested in this issue is assumed to be what is wanted in the next
1273 // reclaim.
1274 pBufConfig->frameLength = pDevExt->frameLength;
1275 pBufConfig->lengthofData = pDevExt->lengthofData;
1276 // enable to inspect input buffer.
1277 // if (pDevExt->lengthofData > 512)
1278 // asm( " SWBP 0" ); // breakpoint
1281 if (pDevExt->running < 3)
1282 pDevExt->running++;
1284 // Goal is to align timing so synchronized with forthcoming
1285 // "DIB_waitForData (... pDevExt->lengthofData);"
1286 // in DIB_reclaim(), servicing PAF_SIO_REQUEST_NEWFRAME, for PAF_SOURCE_PCM/DSD?.
1287 // ** need to revise above DSD handling so it works w/ this calc. **
1288 {
1289 int futureAvail = GetFutureAvail (pBufConfig);
1290 // GetFutureAvail() returns 0 if full buffer requested or if no requests outstanding
1291 // -- 0 (empty) can't be right interpretation here, on account of foregoing issueChild()
1292 if( ! futureAvail)
1293 futureAvail = pBufConfig->sizeofBuffer / pBufConfig->sizeofElement; // total words in buffer
1294 pDevExt->numSamplesExtra = (XDAS_Int16) (futureAvail - pDevExt->frameLength);
1295 }
1297 return status;
1298 } // DIB_requestFrame
1300 // -----------------------------------------------------------------------------
1302 Int DIB_reset (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1303 {
1304 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1305 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
1306 int status, numChan;
1309 //?? Do we need a shutdown to handle queue problems?
1310 // or are there no problems since we use one frame
1311 status = DEV2_idle (pChild, 1);
1312 if(status)
1313 return status;
1315 if (pBufConfig) {
1316 int sizeofStride;
1317 pBufConfig->pntr = pBufConfig->base;
1318 pBufConfig->head = pBufConfig->base;
1319 pBufConfig->futureHead = pBufConfig->base;
1321 pBufConfig->lengthofData = 0;
1323 //devices must? support 2byte words
1324 pBufConfig->sizeofElement = 2;
1325 status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1326 if(status)
1327 return status;
1329 status = DEV2_ctrl (pChild, PAF_SIO_CONTROL_GET_NUMCHANNELS, (Arg) &numChan);
1330 if(status)
1331 return status;
1332 pBufConfig->stride = numChan;
1334 // compute and use *effective buffer size*
1335 sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride;
1336 pBufConfig->sizeofBuffer = pBufConfig->allocation/sizeofStride*sizeofStride;
1338 //hack -- save status context for use in close
1339 pDevExt->pInpBufStatus = pBufConfig->pBufStatus;
1340 pBufConfig->pBufStatus->lastFrameFlag = 0;
1342 pDevExt->bufConfig = *pBufConfig;
1343 pDevExt->pSync = pBufConfig->base;
1344 }
1346 pDevExt->syncState = SYNC_NONE;
1347 pDevExt->scanState = SCANNED_NONE;
1348 pDevExt->pcmTimeout = 0;
1349 pDevExt->deferredError = 0;
1351 pDevExt->numSamplesSinceDTS = 0;
1352 pDevExt->numSamplesExtra = 0;
1354 pDevExt->headerSize = 0;
1355 pDevExt->running = 0;
1357 return 0;
1358 } // DIB_reset
1360 // -----------------------------------------------------------------------------
1361 // Notes:
1362 // 1. The amount of data to be scanned will not result in a buffer wrap-around
1363 // 2. (1) is currently met from the two locations that call this function
1364 // a. DIB_getSync
1365 // b. DIB_reclaim (for PCM)
1366 // 3. We require that pTimeout != NULL since we dereference to make a const
1368 Int DIB_syncScan (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout)
1369 {
1370 DIB_DeviceExtension * restrict pDevExt = (DIB_DeviceExtension *)device->object;
1371 MdInt * restrict pTail, * restrict pShadowTail, * restrict pSync;
1372 MdInt *pLocalTail, pc;
1373 XDAS_Int8 scanState;
1374 XDAS_UInt32 zeroCount;
1375 int stride, numLeft, i, datId;
1376 int status, foundDTS = 0;
1377 Uns scanCount, pageSize;
1378 PAF_SIO_IALG_Obj *pObj = pDevExt->pSioIalg;
1379 PAF_SIO_IALG_Config *pAlgConfig = &pObj->config;
1380 const int timeoutChanged = (*pTimeout != 2 * pBufConfig->pBufStatus->unknownTimeout);
1381 MdInt DTSHDSubType;
1383 // .........................................................................
1385 // works for both SYNC_NONE and SYNC_PCM
1386 numLeft = min (*pTimeout, GetNumAvail(pBufConfig));
1388 pTail = pBufConfig->pntr.pMdInt;
1389 pShadowTail = pBufConfig->pntr.pMdInt;
1391 // if scratch buffer present then assume it is needed for paging
1392 pageSize = numLeft*pBufConfig->sizeofElement;
1394 Log_info3("DIB: Entered DIB_syncScan with pTail = 0x%x & numLeft = %d, timeout = %d", pTail, numLeft, *pTimeout); // GJ Debug
1397 if ((pAlgConfig->numRec > 1) && pAlgConfig->pMemRec[1].base && (pAlgConfig->pMemRec[1].size >= pageSize)) {
1398 pTail = pAlgConfig->pMemRec[1].base;
1399 datId = DAT_copy ((void *) pShadowTail, (void *) pTail, pageSize);
1400 DAT_wait (datId);
1401 }
1403 if (pBufConfig->sizeofElement == 4) {
1404 Log_info0("DIB: SyncScan - Inside pBufConfig->sizeofElement == 4"); // GJ Debug
1405 stride = 2;
1406 pTail += 1; // point at MSB
1407 pShadowTail += 1;
1408 }
1409 else
1410 stride = 1;
1412 // .........................................................................
1414 // scan until out of available data or a sync found
1415 scanCount = 0;
1416 zeroCount = pDevExt->zeroCount;
1417 scanState = pDevExt->scanState;
1418 pSync = pDevExt->pSync.pMdInt;
1420 Log_info3("DIB: Entered DIB_syncScan with zeroCount = %d & scanState = %d, pSync = 0x%x", zeroCount, scanState, pSync); // GJ Debug
1422 // scan until out of available data or a sync found
1423 for (i=0; i < numLeft; i++) {
1424 MdInt tail = pTail[i*stride];
1426 // assumes SCANNED_NONE = 0
1427 if (!scanState) {
1428 if (tail == IEC_PA) {
1429 // since above code handles ongoing sync we are
1430 // safe to check for extended sync here. i.e.
1431 // two zeros before PA.
1432 if (zeroCount >= 2) {
1433 scanState = SCANNED_IEC_PA;
1434 pSync = &pShadowTail[i*stride];
1435 }
1436 }
1437 else if (tail == DTS14_SYNC_A) {
1438 scanState = SCANNED_DTS14_SYNC_A;
1439 pSync = &pShadowTail[i*stride];
1440 }
1441 else if (tail == DTS16_SYNC_A) {
1442 scanState = SCANNED_DTS16_SYNC_A;
1443 pSync = &pShadowTail[i*stride];
1444 }
1446 // limit count to prevent wrap around
1447 zeroCount = min (zeroCount+1,INT_MAX - 1);
1448 if (tail != 0x0000)
1449 zeroCount = 0;
1451 // don't start counting until we get the first non-zero
1452 // sample while UNKNOWN. Note we don't have to worry
1453 // about the other scanCount increments since these
1454 // only occur after the first non-zero sample.
1455 //
1456 // so don't count unless
1457 // . we are already started counting (in this call) ||
1458 // . we started counting in an earlier scanForSync (timeout has changed) ||
1459 // . the last sample was non-zero
1460 if (scanCount || (tail != 0x0000) || timeoutChanged)
1461 {
1462 //Log_info3("DIB: DIB_syncScan scanCount = %d tail = %d timeoutChanged = %d", scanCount, tail, timeoutChanged); // GJ Debug
1463 scanCount += 1;
1464 }
1467 continue;
1468 }
1470 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1472 switch (scanState) {
1474 case SCANNED_DTS16_SYNC_A:
1475 if (tail == DTS16_SYNC_B) {
1476 scanState = SCANNED_DTS16_SYNC_B;
1477 scanCount += 1;
1478 }
1479 else
1480 scanState = SCANNED_NONE;
1481 break;
1483 // wait for header data to get payload size via
1484 // nblks/fsize
1485 case SCANNED_DTS16_SYNC_B:
1486 // use extended sync
1488 if ((short)(tail & 0xFC00) == DTS16_SYNC_C) {
1489 scanState = SCANNED_DTS16_SYNC_C;
1490 scanCount += 1;
1491 }
1492 else
1493 scanState = SCANNED_NONE;
1494 break;
1496 // `````````````````````````````````````````````````````````````````````````
1497 // check for 2nd word of DTS-14 sync
1498 case SCANNED_DTS14_SYNC_A:
1499 if (tail == DTS14_SYNC_B) {
1500 scanState = SCANNED_DTS14_SYNC_B;
1501 scanCount += 1;
1502 }
1503 else
1504 scanState = SCANNED_NONE;
1505 break;
1507 // check for 3rd word of DTS-14 sync
1508 case SCANNED_DTS14_SYNC_B:
1509 // if here then looking for extended 38 bit sync
1510 if ((short)(tail & 0xFFF0) == DTS14_SYNC_C) {
1511 scanState = SCANNED_DTS14_SYNC_C;
1512 scanCount += 1;
1513 }
1514 else
1515 scanState = SCANNED_NONE;
1516 break;
1518 // wait for header data to get payload size via
1519 // nblks/fsize
1520 case SCANNED_DTS14_SYNC_C:
1521 scanState = SCANNED_DTS14_SYNC_D;
1522 scanCount += 1;
1523 break;
1525 // `````````````````````````````````````````````````````````````````````````
1526 // if here then all of header is buffered
1527 case SCANNED_DTS16_SYNC_C:
1528 case SCANNED_DTS14_SYNC_D:
1529 // update sync to point at beginning of DTS header as syncScanDTS uses this info
1530 pDevExt->scanState = scanState;
1531 pDevExt->pSync.pMdInt = pSync;
1532 status = DIB_FTABLE_syncScanDTS (device, pBufConfig, pTimeout, (XDAS_UInt16 *) &pShadowTail[i*stride]);
1533 scanState = pDevExt->scanState;
1534 if (status)
1535 return status;
1536 foundDTS = 1;
1537 if (pDevExt->syncState == SYNC_ONE)
1538 goto syncScanExit;
1539 break;
1541 // `````````````````````````````````````````````````````````````````````````
1543 // note that the round about detection of IEC only
1544 // happens for the first sync so the extra states are OK.
1545 case SCANNED_IEC_PA:
1546 if (tail == IEC_PB) {
1547 scanState = SCANNED_IEC_PB;
1548 scanCount += 1;
1549 Log_info0("DIB: SyncScan Inside case - SCANNED_IEC_PA - if path"); // GJ Debug
1550 }
1551 else
1552 {
1553 Log_info0("DIB: SyncScan Inside case - SCANNED_IEC_PA - else path"); // GJ Debug
1554 scanState = SCANNED_NONE;
1555 }
1556 break;
1558 case SCANNED_IEC_PB:
1559 // Update scanCount here since, at this point, we are confident that
1560 // this is a proper IEC stream. Regardless if we ignore it our not.
1561 // Therefore we want to properly signal that this data has been scanned.
1562 scanCount += 1;
1564 // check for IEC pause packets at this time and if required ignore them.
1565 // By construction we are guaranteed to have tail=PC at this time.
1566 if ((pBufConfig->pBufStatus->mode == MODE_NO_ZERORUNRESTART) ||
1567 (pBufConfig->pBufStatus->mode == MODE_NO_ZERORUN)) {
1568 MdInt pc = tail & 0x1F;
1570 if ((pc == 0) || (pc == 3)) {
1571 scanState = SCANNED_NONE;
1572 break;
1573 }
1574 }
1576 scanState = SCANNED_IEC_PC;
1577 break;
1579 case SCANNED_IEC_PC:
1580 pLocalTail = pSync;
1581 IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 2);
1582 pc = *pLocalTail & 0x1F;
1583 pDevExt->headerSize = IEC_HEADER_SIZE;
1585 Log_info0("DIB: Sync Scan - Inside case: SCANNED_IEC_PC"); // GJ Debug
1586 // Handle DTSHD subtype (LBR)
1587 if (pc == 0x11) {
1588 pDevExt->headerSize +=6;
1589 DTSHDSubType = (*pLocalTail & 0x700)>>8;
1590 }
1591 // DDP or THD
1592 if (pc == 21 || pc ==22) {
1593 TRACE((&TR_MOD, "Dolby: useIECSubType is 0x%x.\n", pBufConfig->pBufStatus->useIECSubType));
1594 if (pBufConfig->pBufStatus->useIECSubType == 1) {
1595 unsigned char IECSubType = *pLocalTail & 0x60;
1596 TRACE((&TR_MOD, "Dolby: IECSubType is 0x%x.\n", IECSubType));
1597 if (IECSubType != 0) {
1598 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
1599 pDevExt->frameLength = 0;
1600 }
1601 }
1602 }
1603 // don't know how to support other types
1604 if (pc > 22)
1605 {
1606 Log_info1("DIB: Unknown IEC type 0x%x encountered.\n", pc); // GJ Debug
1607 return DIBERR_SYNC;
1608 }
1610 pDevExt->syncState = SYNC_ONE;
1611 pBufConfig->pntr.pMdInt = pSync;
1612 pDevExt->sourceProgram = iecPafSource[pc];
1614 Log_info2("source is %d. pc is %d.", iecPafSource[pc], pc); // GJ Debug
1615 //TRACE((&TR_MOD, "source is %d. pc is %d.\n", iecPafSource[pc], pc));
1617 if (pc == 0x11 && DTSHDSubType == 3 && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
1618 pDevExt->sourceProgram = PAF_SOURCE_DXP; // LBR is 23
1620 pDevExt->frameLength = pDevExt->pIECFrameLength[pc];
1621 pDevExt->lengthofData = pDevExt->frameLength;
1622 if (pc == 1)
1623 pDevExt->frameLength = 4288;
1624 else if (pc == 0x11) {
1625 pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
1626 pDevExt->lengthofData = pDevExt->frameLength;
1627 }
1629 goto syncScanExit;
1631 } // switch
1632 } // for
1634 // .............................................................................
1636 syncScanExit:
1637 Log_info4("DIB inside syncScanExit. pTimeout = %d, scanCount = %d, zeroCount = %d, numLeft = %d", *pTimeout,scanCount, zeroCount, numLeft ); // GJ Debug
1638 pDevExt->zeroCount = zeroCount;
1639 pDevExt->scanState = scanState;
1640 pDevExt->pSync.pMdInt = pSync;
1642 if (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger)
1643 pBufConfig->pBufStatus->zeroRun = 1;
1644 else
1645 pBufConfig->pBufStatus->zeroRun = 0;
1647 // If detected an initial DTS sync in a previous buffer then add the
1648 // number of samples in this buffer to the tally.
1649 // TODO: should we add numLeft instead of lengthofData?
1650 if (!foundDTS && pDevExt->numSamplesSinceDTS)
1651 pDevExt->numSamplesSinceDTS += pBufConfig->lengthofData;
1653 if (*pTimeout > scanCount)
1654 *pTimeout -= scanCount;
1655 else {
1656 *pTimeout = 0;
1657 return 0;
1658 }
1660 // This flushes the current scanned buffer if a sync is not found
1661 // Note that this code is not executed when *pTimeout = 0.
1662 // TODO: should this be moved elsewhere. Like in requestFrame?
1663 // seems like this should be done in request frame for continuous modes
1664 // and in getSync for traditional modes.
1665 // What does it mean that this is not executed when we have timed out to PCM
1666 if (pDevExt->syncState == SYNC_NONE || pDevExt->syncState == SYNC_AUTO) {
1667 IncrementPtr (pBufConfig, (Ptr *) &pBufConfig->pntr.pMdInt, numLeft);
1668 return 0;
1669 }
1671 return 0;
1672 } // DIB_syncScan
1674 // -----------------------------------------------------------------------------
1675 // Assumes scanState is SCANNED_DTS16_SYNC_C or SCANNED_DTS14_SYNC_D
1677 Int DIB_syncScanDTS (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout, XDAS_UInt16 *pHeaderEnd)
1678 {
1679 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1680 Int sourceProgram = (pDevExt->scanState == SCANNED_DTS14_SYNC_D) ? PAF_SOURCE_DTS14 : PAF_SOURCE_DTS16;
1681 float sampleRate = PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD];
1682 MdInt *pLocalTail, pc, pd;
1683 int nblks;
1686 // compute repetition rate as predicted by DTS header
1687 pLocalTail = pDevExt->pSync.pMdInt;
1688 IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 2);
1689 pc = *pLocalTail;
1690 if (pDevExt->scanState == SCANNED_DTS16_SYNC_C)
1691 nblks = (pc & 0x01FC) >> 2;
1692 else {
1693 IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 1);
1694 pd = *pLocalTail;
1695 nblks = (pc & 0x7) << 4;
1696 nblks |= (pd & 0x3C00) >> 10;
1697 }
1699 // if samplerate > 44.1k and DTS16 bit CD then report as DTS-DVD
1700 // this is a work around to the possibility that DTS-DVD is being
1701 // sent but, due to the variance in input recording, we may have
1702 // missed the IEC header. This is predicated on the enable register
1703 if (pBufConfig->pBufStatus->reportDTS16AsDTSForLargeSampleRate &&
1704 (sampleRate > 44100) && (sourceProgram == PAF_SOURCE_DTS16))
1705 sourceProgram = PAF_SOURCE_DTS;
1707 // point at LSB, if neceesary, so that space calculation is correct
1708 if (pBufConfig->sizeofElement == 4)
1709 pHeaderEnd -= 1;
1711 // If in PCM mode then require double sync, at an appropriate spacing,
1712 // in order to determine DTS validity.
1713 if (pDevExt->syncState == SYNC_PCM) {
1714 int diff;
1716 // If we have started counting, i.e. found a previous sync,
1717 // then compute sync spacing.
1718 if (pDevExt->numSamplesSinceDTS) {
1719 // determine distance since last sync
1720 // pHeaderEnd, which points at the end of the DTS header, is guaranteed
1721 // to be in the active buffer. Whereas the pointer to the beginning of the header (pSync)
1722 // may have occured in the previous buffer.
1723 diff = ((int) pHeaderEnd - (int) pBufConfig->pntr.pVoid);
1724 if (diff < 0)
1725 diff += pBufConfig->sizeofBuffer;
1726 diff /= pBufConfig->sizeofElement;
1727 diff += pDevExt->numSamplesSinceDTS;
1729 // if spacing incorrect then reset sample count to
1730 // force next conditional to be true.
1731 if (diff != (nblks+1)*32*2)
1732 pDevExt->numSamplesSinceDTS = 0;
1733 }
1735 // If this is the 1st sync detected or if this is the second sync
1736 // but the spacing between DTS syncs did not match that predicted by
1737 // NBLKS, then this is not DTS data. Therefore the previous DTS sync
1738 // word was not valid and so it is safe to reset the count based on
1739 // this secondary sync word. This latter sync may or may not be valid;
1740 // we don't know yet. In both cases init sync spacing count, reset
1741 // scan state, and continue. Note that there is a positive, albeit
1742 // quite small, probability of falsing in a pathological case where
1743 // the PCM data, interpreted as a DTS header and used to compute NBLKS,
1744 // actually matches the fake DTS syncs in the PCM file.
1745 if (!pDevExt->numSamplesSinceDTS) {
1746 diff = (int) pBufConfig->head.pVoid - (int) pHeaderEnd;
1747 if (diff <= 0)
1748 diff += pBufConfig->sizeofBuffer;
1749 diff /= pBufConfig->sizeofElement;
1750 pDevExt->numSamplesSinceDTS = diff;
1751 pDevExt->scanState = SCANNED_NONE;
1752 return 0;
1753 }
1754 } //SYNC_PCM
1756 pDevExt->lengthofData = (nblks+1)*32*2;
1757 if (pDevExt->scanState == SCANNED_DTS16_SYNC_C)
1758 pDevExt->frameLength = pDevExt->lengthofData + 4;
1759 else
1760 pDevExt->frameLength = pDevExt->lengthofData + 6;
1762 pDevExt->syncState = SYNC_ONE;
1763 pBufConfig->pntr = pDevExt->pSync;
1764 pDevExt->sourceProgram = sourceProgram;
1766 return 0;
1767 } //DIB_syncScanDTS
1769 // -----------------------------------------------------------------------------
1770 // This function is responsible for verifying bitstream sync (if applicable) and
1771 // configuring the sizes of the next frame of data.
1773 Int DIB_initFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1774 {
1775 DIB_DeviceExtension * restrict pDevExt = (DIB_DeviceExtension *) device->object;
1776 MdInt * restrict pTail;
1777 MdInt pa, pb, pc;
1778 unsigned char DTSHDSubType;
1779 PAF_UnionPointer ac3SearchPtr;
1782 // MID 810
1783 // TODO: is this needed anymore? can we combine above and this?
1784 // I don't think this is needed since pSync is guaranteed to be
1785 // valid under all cases where this function is called.
1786 if (!(pDevExt->scanState == SCANNED_DTS14_SYNC_D ||
1787 pDevExt->scanState == SCANNED_DTS16_SYNC_C ||
1788 pDevExt->scanState == SCANNED_IEC_PC ))
1789 return 0;
1791 // minimum possible distance from current IEC sync to next is 1856 words
1792 // capture this here before we update pSync following
1793 ac3SearchPtr = pDevExt->pSync;
1795 // for steady state compute expected sync location
1796 if (pDevExt->syncState == SYNC_ONGOING)
1797 IncrementPtr (pBufConfig, &pDevExt->pSync.pVoid, pBufConfig->lengthofData);
1799 pTail = pDevExt->pSync.pMdInt;
1800 pa = *pTail;
1801 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1802 pb = *pTail;
1803 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1804 pc = *pTail;
1805 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1807 switch (pDevExt->scanState) {
1808 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1810 case SCANNED_DTS14_SYNC_D:
1811 // check sync (extended sync checked above for 1st sync)
1812 if ((pa != DTS14_SYNC_A) || (pb != DTS14_SYNC_B) || ((pc & 0xFC00) != (DTS14_SYNC_C & 0xFC00)))
1813 return DIBERR_SYNC;
1814 break;
1816 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1818 case SCANNED_DTS16_SYNC_C:
1819 // check sync (extended sync checked above for 1st sync)
1820 if ((pa != DTS16_SYNC_A) || (pb != DTS16_SYNC_B))
1821 return DIBERR_SYNC;
1822 break;
1824 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1826 case SCANNED_IEC_PC:
1827 // check for sync
1828 // special handling for AC3 variable bit rate (VBR)
1829 // start looking for sync at max payload sync location and
1830 // scan forward. Note that getSync() has waited for
1831 // sufficient data to arrive so that we can determine reliably
1832 // the presence or absence of a correct sync.
1834 if ((pa != IEC_PA) || (pb != IEC_PB)) {
1835 PAF_SIO_IALG_Obj *pObj = pDevExt->pSioIalg;
1836 PAF_SIO_IALG_Config *pAlgConfig = &pObj->config;
1837 int scan1, scan2, searchIdx, datId;
1838 const int bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1841 // only extend IEC search in the case of AC3
1842 if (pDevExt->sourceProgram != PAF_SOURCE_AC3)
1843 return DIBERR_SYNC;
1845 // move search ptr to earliest possible location of next sync
1846 IncrementPtr (pBufConfig, &ac3SearchPtr.pVoid, 1856);
1848 // compute number of samples between earliest possible sync location
1849 // (ac3SearchPtr) and latest possible sync location (head)
1850 scan1 = (int) pBufConfig->head.pVoid - (int) ac3SearchPtr.pVoid;
1851 if (scan1 < 0) {
1852 // here if search will wrap around so split search into two
1853 // halves to accomodate circular buffer
1854 scan1 = bufEnd - (int) ac3SearchPtr.pVoid;
1855 scan2 = (int) pBufConfig->head.pVoid - (int) pBufConfig->base.pVoid;
1856 }
1857 else
1858 scan2 = 0;
1860 // page if necessary (assume so if second memRec present)
1861 if (pAlgConfig->numRec > 1) {
1862 // if invalid buffer or if page buffer not big enough for either split then error
1863 if (!pAlgConfig->pMemRec[1].base ||
1864 (pAlgConfig->pMemRec[1].size < max(scan1,scan2)))
1865 return DIBERR_UNSPECIFIED;
1867 pTail = (MdInt *) pAlgConfig->pMemRec[1].base;
1868 datId = DAT_copy (ac3SearchPtr.pVoid, (void *) pTail, scan1);
1869 DAT_wait (datId);
1870 }
1871 else
1872 pTail = ac3SearchPtr.pMdInt;
1874 // convert to number of words
1875 scan1 /= pBufConfig->sizeofElement;
1877 // if non-zero must be IEC header, otherwise sync error
1878 // update pointer after check so that it remains
1879 // pointed at first non-zero word when breaking
1880 searchIdx = 0;
1881 while (scan1--) {
1882 if (*pTail != 0) {
1883 // force skip of any possible split scan since we found non-zero word
1884 scan2 = 0;
1885 break;
1886 }
1887 *pTail++;
1888 searchIdx++;
1889 }
1891 // perform second half of circular buffer search if necessary
1892 if (scan2) {
1893 // page if necessary, note no need to check valid buffer
1894 // or space since this is ensured in first scan
1895 if (pAlgConfig->numRec > 1) {
1896 pTail = (MdInt *) pAlgConfig->pMemRec[1].base;
1897 datId = DAT_copy (pBufConfig->base.pVoid, (void *) pTail, scan2);
1898 DAT_wait (datId);
1899 }
1900 else
1901 pTail = pBufConfig->base.pMdInt;
1903 // convert to number of words
1904 scan2 /= pBufConfig->sizeofElement;
1906 while (scan2--) {
1907 if (*pTail != 0)
1908 break;
1909 *pTail++;
1910 searchIdx++;
1911 }
1912 }
1914 // if using paging buffer then translate search pointer back into circular buffer
1915 if (pAlgConfig->numRec > 1) {
1916 pTail = ac3SearchPtr.pMdInt;
1917 IncrementPtr (pBufConfig, (Ptr *) &pTail, searchIdx);
1918 }
1920 // update sync in expection of success, if it is not a sync then no
1921 // harm since it will be ignored then reset
1922 pDevExt->pSync.pMdInt = pTail;
1924 // above search only scans for the first non-zero word.
1925 // here is common check to make sure that non-zero data is an IEC sync.
1926 pa = *pTail;
1927 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1928 pb = *pTail;
1929 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1930 pc = *pTail;
1931 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1932 if ((pa != IEC_PA) || (pb != IEC_PB))
1933 return DIBERR_SYNC;
1934 }
1936 // compute possible DTSHD sub type before masking pc
1937 DTSHDSubType = (pc & 0x700) >> 8;
1939 // mask pc to get data type only
1940 pc = pc & 0x1F;
1942 // don't know how to support other types
1943 // this also ensures that the below array access is bounded
1944 if (pc > 22)
1945 return DIBERR_SYNC;
1947 // continuing frame must be same as current type otherwise
1948 // we return error to force reset of decode and input
1949 // classification state machines
1950 if (pDevExt->sourceProgram != iecPafSource[pc]) {
1951 if (DTSHDSubType == 3 &&
1952 (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <= 48000.0)) {
1953 if (pDevExt->sourceProgram != PAF_SOURCE_DXP)
1954 return DIBERR_SYNC;
1955 }
1956 else
1957 return DIBERR_SYNC;
1958 }
1959 break;
1961 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1962 } //switch
1964 return 0;
1965 } // DIB_initFrame
1967 // -----------------------------------------------------------------------------
1969 Int DIB_waitForData (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 count )
1970 {
1971 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *) device->object;
1972 DEV2_Handle pChild = (DEV2_Handle) &pDevExt->child;
1973 Int status, lock;
1975 Log_info2("DIB_waitForData.%d count = %d", __LINE__, count); // GJ Debug
1976 //TRACE((&TR_MOD, "DIB_waitForData.%d count = %d\n", __LINE__, count));
1978 while (GetNumAvail(pBufConfig) < count) {
1979 PAF_SIO_InputStatus inputStatus;
1981 // query underlying device for lock status & check lock override register
1982 // dont wait without lock
1983 status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS, (Arg) &inputStatus);
1984 if (status)
1985 {
1986 Log_info2("DIB_waitForData.%d SIO2_ctrl() returned %d", __LINE__, status); // GJ Debug
1987 //TRACE((&TR_MOD, "DIB_waitForData.%d SIO2_ctrl() returned %d\n", __LINE__, status));
1988 return status;
1989 }
1990 lock = inputStatus.lock;
1991 #ifndef IGNORE_LOCK_OVERRIDE
1992 if ((pBufConfig->pBufStatus->lockOverride & (XDAS_Int8)0x80) == 0)
1993 {
1994 Log_info1("DIB_waitForData.%d lock = lockOverride\n", __LINE__); // GJ Debug
1995 //TRACE((&TR_MOD, "DIB_waitForData.%d lock = lockOverride\n", __LINE__));
1996 lock = pBufConfig->pBufStatus->lockOverride;
1997 }
1998 #endif
1999 if (!lock)
2000 {
2001 Log_info1("DIB_waitForData.%d no lock, return DIBERR_SYNC\n", __LINE__); // GJ Debug
2002 //TRACE((&TR_MOD, "DIB_waitForData.%d no lock, return DIBERR_SYNC\n", __LINE__));
2003 return DIBERR_SYNC;
2004 }
2005 // check that decoding still requested -- allows for status
2006 // register to be updated via IOS to cancel autoProcessing
2007 if (pDevExt->pDecodeStatus) {
2008 if (pDevExt->pDecodeStatus->sourceSelect == PAF_SOURCE_NONE)
2009 {
2010 Log_info1("DIB_waitForData.%d sourceSelect is NONE, return DIBERR_SYNC", __LINE__); // GJ Debug
2011 //TRACE((&TR_MOD, "DIB_waitForData.%d sourceSelect is NONE, return DIBERR_SYNC\n", __LINE__));
2012 return DIBERR_SYNC;
2013 }
2014 }
2016 Log_info1("DIB_waitForData.%d calling DIB_FTABLE_reclaimChild()", __LINE__); // GJ Debug
2017 //TRACE((&TR_MOD, "DIB_waitForData.%d calling DIB_FTABLE_reclaimChild()\n", __LINE__));
2018 status = DIB_FTABLE_reclaimChild (device, pBufConfig);
2019 if(status)
2020 {
2021 Log_info2("DIB_waitForData.%d DIB_FTABLE_reclaimChild() returned %d", __LINE__, status); // GJ Debug
2022 //TRACE((&TR_MOD, "DIB_waitForData.%d DIB_FTABLE_reclaimChild() returned %d\n", __LINE__, status));
2023 return status;
2024 }
2025 }
2027 return 0;
2028 } // DIB_waitForData
2030 // -----------------------------------------------------------------------------
2031 #ifdef IEC_ENCODE
2033 // FS9 only supports PCM input so return error if not PCM.
2035 Int DIB_requestFrame_957 (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
2036 {
2037 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *) device->object;
2038 int i, head, tail, avail, status;
2041 if (pDevExt->sourceProgram != PAF_SOURCE_PCM)
2042 return DIBERR_SYNC;
2044 // if in steady state then update tail pointer to indicate we are done, i.e. no
2045 // longer own, the last frame of data.
2046 if (pDevExt->running > 1)
2047 IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pBufConfig->lengthofData);
2049 pDevExt->lengthofData = pBufConfig->stride*pDevExt->pcmFrameLength;
2050 pDevExt->frameLength = pDevExt->lengthofData;
2052 // note that due to MID 1037 it is required to check the return status after this call
2053 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
2054 if (status)
2055 return status;
2057 // add extra input delay to account for peak encoder mips
2058 for (i=0; i < 4; i++) {
2059 head = (int) pBufConfig->futureHead.pVoid;
2060 tail = (int) pBufConfig->pntr.pVoid;
2061 // compute how much data we have including outstanding requests
2062 if (head >= tail)
2063 avail = head - tail;
2064 else
2065 avail = head - tail + pBufConfig->sizeofBuffer;
2067 // convert to words
2068 avail /= pBufConfig->sizeofElement;
2069 if (avail < 4*pBufConfig->lengthofData) {
2070 status = DIB_FTABLE_issueChild (device, pBufConfig, pBufConfig->lengthofData, 0);
2071 if (status)
2072 return status;
2073 }
2074 }
2076 pBufConfig->frameLength = pDevExt->frameLength;
2077 pBufConfig->lengthofData = pDevExt->lengthofData;
2079 if (pDevExt->running < 3)
2080 pDevExt->running++;
2082 return 0;
2083 } // DIB_requestFrame_957
2085 #endif /* IEC_ENCODE */
2087 // -----------------------------------------------------------------------------
2089 #ifdef DSD_OVER_SPDIF
2091 Int DIB_requestFrame_patch (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
2092 {
2093 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
2094 int status;
2096 status = DIB_requestFrame (device, pBufConfig);
2097 // For testing DSD over SPDIF i.e. 1 pin vs actual over 6 pin
2098 pDevExt->numSamplesExtra += pDevExt->lengthofData;
2099 pDevExt->lengthofData *=6;
2100 pDevExt->numSamplesExtra -= pDevExt->lengthofData;
2102 return status;
2103 } // DIB_requestFrame
2105 Int DIB_getSync_patch (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
2106 {
2107 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
2108 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
2109 int status;
2111 status=DIB_getSync (device, pBufConfig );
2112 if(status)
2113 return status;
2115 pBufConfig->sizeofElement = 2;
2116 status = SIO2_ctrl (pChild,(Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
2117 if (status)
2118 return status;
2120 // compute and use *effective buffer size*
2121 {
2122 int sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride;
2123 pBufConfig->sizeofBuffer = pBufConfig->allocation/sizeofStride*sizeofStride;
2124 }
2125 //..........................................................................
2127 return 0;
2128 } // DIB_getSync_patch
2130 #endif /* DSD_OVER_SPDIF */
2132 // -----------------------------------------------------------------------------