ACQ2XX_API
AcqType.cpp
Go to the documentation of this file.
00001 /* ------------------------------------------------------------------------- */
00002 /* file AcqType.cpp                                                          */
00003 /* ------------------------------------------------------------------------- */
00004 /*   Copyright (C) 2009 Peter Milne, D-TACQ Solutions Ltd
00005  *                      <Peter dot Milne at D hyphen TACQ dot com>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of Version 2 of the GNU General Public License
00009     as published by the Free Software Foundation;
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
00019 /* ------------------------------------------------------------------------- */
00020 
00021 /** @file AcqType.cpp Encapsulates ACQ2xx product design details .
00022          like channel mapping, number of channels, word size.
00023 
00024          * pulls details from card using get.personality
00025         
00026  * Refs: see ICD for frame definition
00027 */
00028 #include "local.h"
00029 
00030 #include <iostream>
00031 #include <string>
00032 #include <map>
00033 #include <stdlib.h>
00034 #include "acq2xx_api.h"
00035 #include "acq_transport.h"
00036 #include "AcqType.h"
00037 
00038 #include "string.h"
00039 
00040 #define CMD     128
00041 #define REPLY   512
00042 
00043 
00044 using namespace std;
00045 
00046 #include <errno.h>
00047 #include <sys/mman.h>
00048 #include <sys/types.h>
00049 #include <sys/stat.h>
00050 #include <fcntl.h>
00051 
00052 #define TS_SHM  "/dev/shm/acq_timestamp"
00053 
00054 class FakeTimestamp {
00055         int fd;
00056         void *mapping;
00057 
00058         bool make_mapping(void){
00059                 mapping = mmap(0, sizeof(unsigned long), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
00060                 return mapping != MAP_FAILED;
00061         }
00062         void init_value(void){
00063                 unsigned long ts = 0;
00064                 write(fd, &ts, sizeof(ts));
00065         }
00066         FakeTimestamp() {
00067                 if ((fd = open(TS_SHM, O_RDWR)) >= 0){
00068                         if (!make_mapping()){
00069                                 init_value();
00070                                 if (!make_mapping()){
00071                                         err("make_mapping failed");
00072                                         exit(errno);
00073                                 }
00074                         }
00075                 }else{
00076                         fd = open(TS_SHM, O_RDWR|O_CREAT);
00077                         if (fd < 0){
00078                                 perror(TS_SHM);
00079                                 exit(errno);
00080                         }else{
00081                                 init_value();
00082                                 if (!make_mapping()){
00083                                         err("make_mapping failed");
00084                                         exit(errno);
00085                                 }
00086                         }
00087                 }
00088         }
00089         ~FakeTimestamp() {
00090                 munmap(mapping, sizeof(unsigned long));
00091                 close(fd);
00092         }
00093 public:
00094         static FakeTimestamp& instance() {
00095                 static FakeTimestamp _instance;
00096                 return _instance;
00097         }
00098 
00099         unsigned long getTimeStamp(void) {
00100                 return *(unsigned long*)mapping;
00101         }
00102         unsigned long updateTimeStamp(long delta) {
00103                 return *(unsigned long*)mapping = getTimeStamp() + delta;
00104         }
00105 };
00106 
00107 static double last_time = -1.0;
00108 
00109 class Acq196EventSignature: public NewEventSignature {
00110         unsigned long long timestamp;
00111 
00112         static long fake_it_usecs;
00113 
00114         Acq196EventSignature(
00115                         short _raw[], unsigned long _sample_cursor,
00116                         int _rowlen) :
00117                                 NewEventSignature(_raw, _sample_cursor, _rowlen)
00118         {
00119                 if (fake_it_usecs > 0){
00120                         timestamp =
00121                                 FakeTimestamp::instance().updateTimeStamp(fake_it_usecs);
00122                 }else{
00123                         const u16 lsw = _raw[16];
00124                         const u16 msw = _raw[17];
00125 
00126                         u32 ts = (msw <<16) | lsw;
00127                         timestamp = ts;
00128                         dbg(1, "01: timestamp: %04x|%04x %08llx",
00129                                         msw<<16, lsw, timestamp);
00130                 }
00131 
00132         }
00133 public:
00134         virtual unsigned long long  getTimeStamp(void) const {
00135                 return timestamp;
00136         }
00137         virtual double timeInSeconds(void) const {
00138                 double time_now = timestamp * Clock::es_clock_ns/1e9;
00139                 if (time_now == last_time){
00140                         err("time_now == last_time %f", time_now);
00141                 }
00142                 last_time = time_now;
00143                 return time_now;
00144         }
00145 
00146         static NewEventSignature* create(
00147                         short _raw[], unsigned long _sample_cursor, int _rowlen);
00148 };
00149 
00150 long Acq196EventSignature::fake_it_usecs = -1;
00151 
00152 class Acq196AcqType : public AcqType {
00153 
00154 public:
00155         Acq196AcqType(int _nchannels, int _word_size = 2) :
00156                 AcqType("ACQ196", _nchannels, _word_size)               
00157         {
00158                 info("model:%s nchannels:%d word_size:%d\n",
00159                      model.c_str(), nchan, word_size);
00160 
00161                 DumpDef::common_timebase = true;
00162         }
00163         Acq196AcqType() :
00164                 AcqType("ACQ196", 96, sizeof(short))            
00165         {
00166         }
00167         virtual int getChannelOffset(int physchan) const {
00168                 if (physchan >= 1 && physchan <= 96){
00169                         return LUT[physchan];
00170                 }else{
00171                         return -1;
00172                 }
00173         };
00174 
00175         static const int LUT[96+1];     /* index from 1 */
00176 
00177         virtual NewEventSignature* createES(
00178                 short _raw[], unsigned long _sample_cursor) const
00179         {
00180                 return Acq196EventSignature::create(
00181                         _raw, _sample_cursor, nchan*word_size);
00182         }
00183 };
00184 
00185 const int Acq196AcqType::LUT[96+1] = {
00186         /* [ 0] */ -1,
00187         /* [ 1] */  0,
00188         /* [ 2] */ 16,
00189         /* [ 3] */  1,
00190         /* [ 4] */ 17,
00191         /* [ 5] */  8,
00192         /* [ 6] */ 24,
00193         /* [ 7] */  9,
00194         /* [ 8] */ 25,
00195         /* [ 9] */  2,
00196         /* [10] */ 18,
00197         /* [11] */  3,
00198         /* [12] */ 19,
00199         /* [13] */ 10,
00200         /* [14] */ 26,
00201         /* [15] */ 11,
00202         /* [16] */ 27,
00203         /* [17] */  4,
00204         /* [18] */ 20,
00205         /* [19] */  5,
00206         /* [20] */ 21,
00207         /* [21] */ 12,
00208         /* [22] */ 28,
00209         /* [23] */ 13,
00210         /* [24] */ 29,
00211         /* [25] */  6,
00212         /* [26] */ 22,
00213         /* [27] */  7,
00214         /* [28] */ 23,
00215         /* [29] */ 14,
00216         /* [30] */ 30,
00217         /* [31] */ 15,
00218         /* [32] */ 31,
00219         /* [33] */ 32,
00220         /* [34] */ 48,
00221         /* [35] */ 33,
00222         /* [36] */ 49,
00223         /* [37] */ 40,
00224         /* [38] */ 56,
00225         /* [39] */ 41,
00226         /* [40] */ 57,
00227         /* [41] */ 34,
00228         /* [42] */ 50,
00229         /* [43] */ 35,
00230         /* [44] */ 51,
00231         /* [45] */ 42,
00232         /* [46] */ 58,
00233         /* [47] */ 43,
00234         /* [48] */ 59,
00235         /* [49] */ 36,
00236         /* [50] */ 52,
00237         /* [51] */ 37,
00238         /* [52] */ 53,
00239         /* [53] */ 44,
00240         /* [54] */ 60,
00241         /* [55] */ 45,
00242         /* [56] */ 61,
00243         /* [57] */ 38,
00244         /* [58] */ 54,
00245         /* [59] */ 39,
00246         /* [60] */ 55,
00247         /* [61] */ 46,
00248         /* [62] */ 62,
00249         /* [63] */ 47,
00250         /* [64] */ 63,
00251         /* [65] */ 64,
00252         /* [66] */ 80,
00253         /* [67] */ 65,
00254         /* [68] */ 81,
00255         /* [69] */ 72,
00256         /* [70] */ 88,
00257         /* [71] */ 73,
00258         /* [72] */ 89,
00259         /* [73] */ 66,
00260         /* [74] */ 82,
00261         /* [75] */ 67,
00262         /* [76] */ 83,
00263         /* [77] */ 74,
00264         /* [78] */ 90,
00265         /* [79] */ 75,
00266         /* [80] */ 91,
00267         /* [81] */ 68,
00268         /* [82] */ 84,
00269         /* [83] */ 69,
00270         /* [84] */ 85,
00271         /* [85] */ 76,
00272         /* [86] */ 92,
00273         /* [87] */ 77,
00274         /* [88] */ 93,
00275         /* [89] */ 70,
00276         /* [90] */ 86,
00277         /* [91] */ 71,
00278         /* [92] */ 87,
00279         /* [93] */ 78,
00280         /* [94] */ 94,
00281         /* [95] */ 79,
00282         /* [96] */ 95
00283 };
00284 
00285 
00286 class NullAcqType : public AcqType {
00287 public:
00288         NullAcqType() :
00289         AcqType("null", 96, sizeof(short))
00290         {}
00291 
00292         virtual int getChannelOffset(int physchan) const {
00293                 return physchan;
00294         }
00295 };
00296 
00297 
00298 class Acq132AcqType : public AcqType {
00299         
00300 public:
00301         Acq132AcqType(const string _model, int _nchannels, int _word_size) :
00302                 AcqType(_model, _nchannels, _word_size)
00303         {
00304                 dbg(1, "model:%s nchannels:%d word_size:%d",
00305                      model.c_str(), nchan, word_size);
00306         }
00307         virtual int getChannelOffset(int physchan) const {
00308                 // @@TODO ACQ132 is different
00309                 return physchan;
00310         }       
00311 };
00312 
00313 class Acq164AcqType : public AcqType {
00314 public:
00315         Acq164AcqType(int _nchannels, int _word_size = 4) :
00316                 AcqType("ACQ164", _nchannels, _word_size)               
00317         {
00318                 info("model:%s nchannels:%d word_size:%d\n",
00319                      model.c_str(), nchan, word_size);
00320         }
00321         Acq164AcqType() :
00322                 AcqType("ACQ164", 64, 4)                
00323         {
00324         }
00325         virtual int getChannelOffset(int physchan) const {
00326                 if (physchan >= 1 && physchan <= 64){
00327                         return LUT[physchan];
00328                 }else{
00329                         return -1;
00330                 }
00331         };
00332 
00333         static const int LUT[64+1];     /* index from 1 */
00334 };
00335 
00336 const int Acq164AcqType::LUT[64+1] = {
00337         /* 0 */ -1,
00338         /* 1 */ 0,
00339         /* 2 */ 4,
00340         /* 3 */ 8,
00341         /* 4 */ 12,
00342         /* 5 */ 1,
00343         /* 6 */ 5,
00344         /* 7 */ 9,
00345         /* 8 */ 13,
00346         /* 9 */ 2,
00347         /*10 */ 6,
00348         /*11 */ 10,
00349         /*12 */ 14,
00350         /*13 */ 3,
00351         /*14 */ 7,
00352         /*15 */ 11,
00353         /*16 */ 15,
00354         /*17 */ 19,
00355         /*18 */ 23,
00356         /*19 */ 27,
00357         /*20 */ 31,
00358         /*21 */ 18,
00359         /*22 */ 22,
00360         /*23 */ 26,
00361         /*24 */ 30,
00362         /*25 */ 17,
00363         /*26 */ 21,
00364         /*27 */ 25,
00365         /*28 */ 29,
00366         /*29 */ 16,
00367         /*30 */ 20,
00368         /*31 */ 24,
00369         /*32 */ 28,
00370         /*33 */ 32,
00371         /*34 */ 36,
00372         /*35 */ 40,
00373         /*36 */ 44,
00374         /*37 */ 33,
00375         /*38 */ 37,
00376         /*39 */ 41,
00377         /*40 */ 45,
00378         /*41 */ 34,
00379         /*42 */ 38,
00380         /*43 */ 42,
00381         /*44 */ 46,
00382         /*45 */ 35,
00383         /*46 */ 39,
00384         /*47 */ 43,
00385         /*48 */ 47,
00386         /*49 */ 51,
00387         /*50 */ 55,
00388         /*51 */ 59,
00389         /*52 */ 63,
00390         /*53 */ 50,
00391         /*54 */ 54,
00392         /*55 */ 58,
00393         /*56 */ 62,
00394         /*57 */ 49,
00395         /*58 */ 53,
00396         /*59 */ 57,
00397         /*60 */ 61,
00398         /*61 */ 48,
00399         /*62 */ 52,
00400         /*63 */ 56,
00401         /*64 */ 60,
00402 };
00403 
00404 class Acq196MacAcqType : public AcqType {
00405 /* original single reference MAC */
00406         static int numchan(const string& refmask);
00407 
00408 public:
00409         Acq196MacAcqType(int _nchan, int _word_size):
00410                 AcqType("ACQ196", _nchan, _word_size)
00411         {
00412                 info("model:%s nchannels:%d word_size:%d\n",
00413                      model.c_str(), nchan, word_size);
00414         }
00415 
00416         Acq196MacAcqType(const string& refmask, int _word_size) :
00417                 AcqType("ACQ196", numchan(refmask), _word_size)         
00418         {
00419                 info("model:%s nchannels:%d word_size:%d\n",
00420                      model.c_str(), nchan, word_size);
00421         }
00422         virtual int getChannelOffset(int physchan) const {
00423                 if (physchan >= 1 && physchan <= 96){
00424                         return Acq196AcqType::LUT[physchan];
00425                 }else{
00426                         return -1;
00427                 }
00428         };
00429 
00430 };
00431 
00432 
00433 int  Acq196MacAcqType::numchan(const string& refmask)
00434 {
00435         /* parse string of form N,N,N,N  : N={1..7} bit mask */
00436         int numblocks = 0;
00437         const char* pr = refmask.c_str();
00438 
00439         while(*pr){
00440                 switch(*pr){
00441                 case '7':
00442                         numblocks += 3; break;
00443                 case '1':
00444                 case '2':
00445                 case '4':
00446                         numblocks += 1; break;
00447                 case '3':
00448                 case '5':
00449                 case '6':
00450                         numblocks += 2; break;
00451                 }
00452                 pr++;
00453         }
00454         return numblocks * 32;
00455 }
00456 
00457 
00458 class PentaLockinAcqType : public AcqType {
00459 
00460         static int getEffectiveNchan(Acq2xx &card);
00461 public:
00462         PentaLockinAcqType(Acq2xx& card, int _nchan, int _word_size):
00463                 AcqType("ACQ196", getEffectiveNchan(card), _word_size)
00464         {
00465                 info("model:%s nchannels:%d word_size:%d\n",
00466                      model.c_str(), nchan, word_size);
00467         }
00468         virtual int getChannelOffset(int physchan) const {
00469                 unsigned block = physchan/32;
00470                 unsigned offset = physchan%32;
00471 
00472                 return 32*block + Acq196AcqType::LUT[offset];
00473         };
00474 };
00475 
00476 
00477 int PentaLockinAcqType::getEffectiveNchan(Acq2xx &card)
00478 {
00479         char reply[REPLY];
00480 
00481         dbg(1, "Get Type From Card\n");
00482         int rc = card.getTransport()->acq2sh(
00483                 "get.sys /dev/LOCKIN/knobs/enable", reply, REPLY);
00484 
00485         if (STATUS_ERR(rc)){
00486                 err("ERROR: failed to get type from card\n");
00487                 return -1;
00488         }
00489 
00490         char hexstring[REPLY];
00491         if (strncmp(reply, "0x", 2) == 0){
00492                 strcpy(hexstring, reply);
00493         }else{
00494                 strcpy(hexstring, "0x");
00495                 strcat(hexstring, reply);
00496         }
00497         unsigned enable_mask = strtoul(hexstring, 0, 0);
00498         unsigned cursor = 0x8000;
00499         int nblocks = 0;
00500         
00501         for (; cursor; cursor >>= 1){
00502                 if (cursor&enable_mask){
00503                         ++nblocks;
00504                 }
00505         }
00506 
00507         dbg(1, "enable:%04x blocks:%d\n", enable_mask, nblocks);
00508 
00509         return nblocks*32;
00510 }
00511 NullAcqType nullAcqTypeInstance;
00512 
00513 
00514 
00515 typedef map<string, string> KeyValueMap;
00516 
00517 KeyValueMap acqPrams;
00518 
00519 static string model;
00520 
00521 #include <strings.h>
00522 
00523 static int parse(const char personality[])
00524 {
00525         const char* l0;
00526         const char* l1;
00527         char aline[80];
00528         char* split;
00529         int nprams = 0;
00530 
00531         for (l0 = personality; (l1 = index(l0, '\n')) != 0; l0 = l1+1){
00532                 strncpy(aline, l0, l1-l0);
00533                 aline[l1-l0] = '\0';
00534                 dbg(1, "line:\"%s\"", aline);
00535                 if (strlen(aline) && (split = index(aline, '='))){
00536                         *split++ = '\0';
00537                         acqPrams[aline] = split;        
00538                 }
00539         }
00540 
00541         map<string,string>::iterator iter;
00542         for (iter = acqPrams.begin(); iter != acqPrams.end(); ++iter){
00543                 dbg(1, "key:\"%s\" value:\"%s\"\n", 
00544                         iter->first.c_str(), iter->second.c_str());
00545                 ++nprams;
00546         }
00547 
00548         dbg(2, "parse done: %d elements\n", acqPrams.size());
00549 
00550         return nprams;
00551 }
00552 
00553 const AcqType& AcqType::_getAcqType(const char personality[], Acq2xx* card)
00554 {
00555         dbg(1, "here with personality \"%s\"", personality);
00556 
00557         if (parse(personality) < 0){
00558                 return nullAcqTypeInstance;     
00559         }
00560         
00561         map<string,string>::iterator iter;
00562         for( iter = acqPrams.begin(); iter != acqPrams.end(); ++iter ) {
00563                 dbg(2, "key:\"%s\" = value:\"%s\"", 
00564                     iter->first.c_str(), iter->second.c_str());
00565         }
00566 
00567         int word_size = atoi(acqPrams["WORD_SIZE"].c_str());
00568         dbg(1, "word_size:%d", word_size);
00569         if (word_size == 0){
00570                 word_size = sizeof(short);
00571         }
00572         int nchan = atoi(acqPrams["AICHAN"].c_str());
00573         dbg(1, "nchan:%d", nchan);
00574         if (nchan == 0){
00575                 nchan = 96;
00576         }
00577 
00578         if (acqPrams["ACQ"] == "acq196" ){
00579                 return *new Acq196AcqType(nchan, word_size);
00580         }else if (acqPrams["ACQ"] == "acq196m"){
00581                 if (acqPrams["HAS_MAC"] == "1"){
00582                         if (acqPrams["REF_MASK"] == ""){
00583                                 return *new Acq196MacAcqType(nchan, word_size);
00584                         }else{
00585                                 return *new Acq196MacAcqType(
00586                                         acqPrams["REF_MASK"], word_size);
00587                         }
00588                 }else if (acqPrams["HAS_MAC"] == "2"){
00589                         if (!card){
00590                                 fprintf(stderr, "needs a card\n");
00591                                 return nullAcqTypeInstance;
00592                         }else{
00593                                 return *new PentaLockinAcqType(
00594                                                 *card, nchan, word_size);
00595                         }
00596                 }else{
00597                         return *new Acq196AcqType(nchan, word_size);
00598                 }
00599         }else if (acqPrams["ACQ"] == "acq164"){
00600                 return *new Acq164AcqType(nchan, word_size);
00601         }else if (acqPrams["ACQ"].find("acq132") != string::npos){
00602                 return *new Acq132AcqType(acqPrams["ACQ"], nchan, word_size);
00603         }else{
00604                 return nullAcqTypeInstance;
00605         }
00606 }
00607 
00608 const AcqType& AcqType::getAcqType(Acq2xx& card)
00609 {
00610         char reply[REPLY];
00611 
00612         dbg(1, "Get Type From Card\n");
00613         int rc = card.getTransport()->acq2sh("get.personality", reply, REPLY);
00614 
00615         if (STATUS_ERR(rc)){
00616                 err("ERROR: failed to get type from card\n");
00617                 return nullAcqTypeInstance;
00618         }else{
00619                 return _getAcqType(reply, &card);
00620         }
00621 }
00622 
00623 
00624 #include <sys/types.h>
00625 #include <sys/stat.h>
00626 #include <fcntl.h>
00627 #include <stdlib.h>
00628 
00629 
00630 const AcqType& AcqType::getAcqType(const char* fname)
00631 {
00632         char errbuf[80];
00633         struct stat sb;
00634         int fd = open(fname, O_RDONLY);
00635         if (fd < 0){
00636                 snprintf(errbuf, sizeof(errbuf),
00637                                 "%s: failed to open config file \"%s\"",
00638                                 FN, fname);
00639                 perror(errbuf);
00640                 return nullAcqTypeInstance;
00641         }
00642         int rc = fstat(fd, &sb);
00643         if (rc != 0){
00644                 snprintf(errbuf, sizeof(errbuf),
00645                                 "%s: failed to fstat() file \"%s\"",
00646                                 FN, fname);
00647                 perror(errbuf);
00648                 return nullAcqTypeInstance;
00649         }
00650 
00651         char *env = (char *)calloc(sb.st_size+1, 1);
00652         int nread = read(fd, env, sb.st_size);
00653         if (nread > 0){
00654                 env[nread] = '\0';
00655                 const AcqType& acqType = _getAcqType(env);
00656                 free(env);
00657                 return acqType;
00658         }else{
00659                 perror("Failed to read env");
00660                 free(env);
00661                 return nullAcqTypeInstance;
00662         }
00663 }
00664 
00665 File::File(string root, string ext, const char* mode) 
00666         : path(root + string("/") + ext)
00667 {
00668         fp = fopen(path.c_str(), mode);
00669         if (fp == 0){
00670                 cerr << "ERROR: failed to open file:" << path << endl;
00671                 exit(-1);
00672         }
00673 }
00674 
00675 File::~File()
00676 {
00677         fclose(fp);
00678 }
00679 
00680 int File::write(double* aDouble)
00681 {
00682 #ifdef __arm
00683 #warning ARM MIXED-ENDIAN DOUBLE HACK
00684         union {
00685                 double dd;
00686                 unsigned us[2];
00687         } mix;
00688         unsigned tmp;
00689         mix.dd = *aDouble;
00690         SWAP(mix.us[0], mix.us[1], tmp);
00691         return fwrite(&mix, sizeof(mix), 1, fp);
00692 #else
00693         return fwrite(aDouble, sizeof(double), 1, fp);
00694 #endif
00695 }
00696 
00697 int File::write(short* aShort)
00698 {
00699         return fwrite(aShort, sizeof(short), 1, fp);
00700 }
00701 
00702 int File::writeln(const char* str){
00703         int rc = fputs(str, fp);
00704         if (str[strlen(str)-1] != '\n'){
00705                 rc += fputs("\n", fp);
00706         }
00707         fflush(fp);
00708         return rc;
00709 }
00710 
00711 #define ACQ196_MAGIC (short)0xaa55
00712 static int is_signature(short *data, int nchan){
00713         for (int ii = 1; ii <= 7; ii += 2){
00714                 if (data[ii] != ACQ196_MAGIC){
00715                         if (ii > 5){
00716                                 dbg(1, "No magic at %d", ii);
00717                                 FILE* pp = popen("/usr/bin/hexdump -ve '96/2 \"%04x \" \"n\"'", "w");
00718                                 fwrite(data, sizeof(short), nchan, pp);
00719                                 pclose(pp);
00720                         }
00721                         return 0;
00722                 }
00723         }
00724 
00725         return 1;
00726 }
00727 
00728 NewEventSignature* Acq196EventSignature::create(
00729                         short _raw[],
00730                         unsigned long _sample_cursor,
00731                         int _rowlen)
00732 {
00733         if (is_signature(_raw, 96)){
00734                 if (fake_it_usecs == -1){
00735                         if (getenv("ACQ_DEMUX_ES_FAKE_IT")){
00736                                 fake_it_usecs = atoi(getenv("ACQ_DEMUX_ES_FAKE_IT"));
00737                         }
00738                 }
00739                 return new Acq196EventSignature(_raw, _sample_cursor, _rowlen);
00740         }else{
00741                 return 0;
00742         }
00743 }
00744 
00745 double Clock::sample_clock_ns;  /** < 0 :: NO TIMEBASE. */
00746 double Clock::es_clock_ns = 1000;       /** ES clocked at 1MHz default */
00747 
00748 bool DumpDef::common_timebase;