[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
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 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)
295 {
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)
310 {
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)
327 {
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)
343 {
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)
413 {
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)
702 {
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)
787 {
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)
808 {
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)
898 {
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 )
911 {
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)
1082 {
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];
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)
1162 {
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)
1212 {
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:
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)
1302 {
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)
1368 {
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
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)
1677 {
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)
1773 {
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 )
1969 {
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)
2035 {
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 )
2091 {
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 )
2105 {
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 // -----------------------------------------------------------------------------