ACQ2XX_API
DataStreamer.cpp
Go to the documentation of this file.
00001 /* ------------------------------------------------------------------------- */
00002 /* file DataStreamer.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 DataStreamer.cpp : example APP, continuous data streaming handler.
00022  *
00023 <pre>
00024   opts:
00025 </pre>
00026  */
00027 
00028 #include <popt.h>
00029 
00030 #include <vector>
00031 
00032 #include "local.h"
00033 #include "acq2xx_api.h"
00034 #include "acq_transport.h"
00035 #include "AcqType.h"
00036 #include "Frame.h"
00037 
00038 #include "DataStreamer.h"
00039 
00040 #define MAXCH 10
00041 #define FRAME_LEN       64
00042 
00043 class Fixup {
00044 public:
00045         virtual ~Fixup() {}
00046 
00047         virtual int fixup(int raw) const { 
00048                 return raw; 
00049         }
00050 };
00051 
00052 
00053 class FixupUnsignedShort: public Fixup {
00054 public:
00055         virtual ~FixupUnsignedShort() {}
00056 
00057         virtual int fixup(int raw) const {
00058                 return raw & 0x0000ffff;
00059         }
00060 };
00061 
00062 
00063 template <class T>
00064 class FrameHandlerComputingStats : public FrameHandler {
00065         static const char* fmt_hex;
00066         static const char* fmt_dec;
00067         static FixupUnsignedShort fixupUnsignedShort;   
00068         static Fixup nullFixup;
00069 
00070         const char *fmt;
00071         const Fixup *fixup;
00072 
00073         void doStats(const AcqType& acqType, const ConcreteFrame<T>* frame)
00074                 /**< output mean of each channel value over frame ..
00075                  **  ie LP filter the output.
00076                  **/
00077         {
00078                 for (int ch = 1; ch <= acqType.getNumChannels(); ++ch){
00079                         const T* ch_data = 
00080                                 frame->getChannel(acqType.getChannelOffset(ch));
00081                         int sum = 0;
00082                         int ii;
00083                         for (ii = 0; ii < FRAME_LEN; ++ii){
00084                                 sum += ch_data[ii];
00085                         }
00086                         printf(fmt, fixup->fixup(sum/FRAME_LEN));
00087                 }
00088         }
00089 
00090 public:
00091         void onFrame(
00092                 Acq2xx& card, const AcqType& acqType, const Frame* frame)
00093         {
00094                 doStats(acqType, dynamic_cast<const ConcreteFrame<T> *>(frame));
00095         }
00096 
00097         FrameHandlerComputingStats(bool format_hex){
00098                 fmt = format_hex? fmt_hex: fmt_dec;
00099                 if (sizeof(T) == sizeof(short) && format_hex){
00100                         fixup = &fixupUnsignedShort;
00101                 }else{
00102                         fixup = &nullFixup;
00103                 }
00104         }
00105 };
00106 
00107 template <> const char* FrameHandlerComputingStats<short>::fmt_hex = "%04x\t";
00108 template <> const char* FrameHandlerComputingStats<short>::fmt_dec = "%6d\t";
00109 
00110 template <> const char* FrameHandlerComputingStats<int>::fmt_hex = "%08x\t";
00111 template <> const char* FrameHandlerComputingStats<int>::fmt_dec = "%11d\t";
00112 
00113 template <class T>
00114 Fixup FrameHandlerComputingStats<T>::nullFixup;
00115 template <class T>
00116 FixupUnsignedShort FrameHandlerComputingStats<T>::fixupUnsignedShort;
00117 
00118 
00119 class FrameHandlerShowsTag : public FrameHandler {
00120         int detail;
00121 
00122         void showMetadata(const Frame& frame){
00123                 char outline[80];
00124                 int cursor = sprintf(outline, "%10d\t%12lld\t", 
00125                         frame.getID(), frame.getStartSampleNumber());
00126 
00127                 if (detail > 1){
00128                         sprintf(outline+cursor, "0x%04x\t0x%04x\t",
00129                                 frame.getDIO(), frame.getExtra());      
00130                 }
00131 
00132                 printf(outline);
00133         }
00134 public:
00135         FrameHandlerShowsTag(int _detail) : 
00136                 detail(_detail) 
00137         {}
00138 
00139         void onFrame(
00140                 Acq2xx& card, const AcqType& acqType, const Frame* frame)
00141         {
00142                 showMetadata(*frame);                  
00143         }
00144 };
00145 
00146 class FrameHandlerPrintsNewline : public FrameHandler {
00147 public:
00148         void onFrame(
00149                 Acq2xx& card, const AcqType& acqType, const Frame* frame)
00150         {
00151                 printf("\n");                  
00152         }       
00153 };
00154 
00155 template <class T> 
00156 class ConcreteDataStreamer : public DataStreamer {
00157         vector<FrameHandler*> frameHandlers;
00158 
00159 public:
00160         ConcreteDataStreamer<T> (Acq2xx& _card, const AcqType& _acqType) :
00161                 DataStreamer(_card, _acqType)
00162         {
00163 
00164         }
00165 
00166         virtual int streamData()
00167         {
00168                 ConcreteFrame<T> frame(acqType);
00169                 Frame* pf = &frame;
00170                 unsigned id = 0;
00171 
00172                 while(1){
00173                         int rc = card.readStreamingFrame(pf, id++);
00174                         dbg(1, "GOT FRAME [%10d] %s sample %lld",
00175                             id , rc == 0? "OK": "ERR",
00176                             frame.getStartSampleNumber());
00177 
00178                         vector<FrameHandler*>::iterator it;
00179                         for (it = frameHandlers.begin(); 
00180                                 it < frameHandlers.end(); ++it){
00181                                 (*it)->onFrame(card, acqType, pf);
00182                         }
00183                 }       
00184                 return 0;
00185         }
00186 
00187         int addFrameHandler(FrameHandler *handler) 
00188         {
00189                 frameHandlers.push_back(handler);
00190                 return 0;
00191         }
00192         int delFrameHandler(FrameHandler *handler)
00193         {
00194                 vector<FrameHandler*>::iterator it;
00195 
00196                 for (it = frameHandlers.begin(); 
00197                         it < frameHandlers.end(); ++it){
00198                         if (*it == handler){
00199                                 frameHandlers.erase(it);
00200                                 break;
00201                         }
00202                 }
00203                 return 0;
00204         }
00205 };
00206 
00207 
00208 
00209 
00210 
00211 DataStreamer* DataStreamer::create(Acq2xx& card, const AcqType& acqType)
00212 {
00213 /** @@todo .. decide other sizes */
00214         if (acqType.getWordSize() == sizeof(short)){
00215                 return new ConcreteDataStreamer<short>(card, acqType);
00216         }else{
00217                 return new ConcreteDataStreamer<int>(card, acqType);
00218         }
00219 }
00220 
00221 
00222 FrameHandler* DataStreamer::createMeanHandler(
00223                 const AcqType& acqType, bool format_hex)
00224 {
00225         if (acqType.getWordSize() == sizeof(short)){
00226                 return new FrameHandlerComputingStats<short>(format_hex);
00227         }else{
00228                 return new FrameHandlerComputingStats<int>(format_hex);
00229         }       
00230 }
00231 FrameHandler* DataStreamer::createTagHandler(int detail)
00232 {
00233         return new FrameHandlerShowsTag(detail);
00234 }
00235 
00236 FrameHandler* DataStreamer::createNewlineHandler() 
00237 {
00238         return new FrameHandlerPrintsNewline();
00239 }