psycho-test-timing.C

00001 /*!@file AppPsycho/psycho-EyeDetect.C pulse a white square on a black
00002    background, useful for testing timing of display. Duration will be
00003    50% of period. We use a YUVOverlay to match our video experiments
00004    
00005 These are valid command options:
00006 bin/psycho-test-timing 100 100 25 0 [01] [01] --sdl-dims=640x480 (no vblank wait)
00007 bin/psycho-test-timing 100 100 25 1 [01] [01] --sdl-dims=640x480 --sdl-vblank-kludge=1
00008 */
00009 
00010 // //////////////////////////////////////////////////////////////////// //
00011 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00012 // University of Southern California (USC) and the iLab at USC.         //
00013 // See http://iLab.usc.edu for information about this project.          //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00016 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00017 // in Visual Environments, and Applications'' by Christof Koch and      //
00018 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00019 // pending; application number 09/912,225 filed July 23, 2001; see      //
00020 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00021 // //////////////////////////////////////////////////////////////////// //
00022 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00023 //                                                                      //
00024 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00025 // redistribute it and/or modify it under the terms of the GNU General  //
00026 // Public License as published by the Free Software Foundation; either  //
00027 // version 2 of the License, or (at your option) any later version.     //
00028 //                                                                      //
00029 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00030 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00031 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00032 // PURPOSE.  See the GNU General Public License for more details.       //
00033 //                                                                      //
00034 // You should have received a copy of the GNU General Public License    //
00035 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00036 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00037 // Boston, MA 02111-1307 USA.                                           //
00038 // //////////////////////////////////////////////////////////////////// //
00039 //
00040 // Primary maintainer for this file: David Berg <dberg@usc.edu>
00041 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/psycho-test-timing.C $
00042 
00043 #include "Component/ModelManager.H"
00044 #include "Image/Image.H"
00045 #include "Image/DrawOps.H"
00046 #include "Devices/ParPort.H"
00047 #include "Psycho/PsychoDisplay.H"
00048 #include "Psycho/PsychoOpts.H"
00049 #include "Component/EventLog.H"
00050 #include "Component/ComponentOpts.H"
00051 #include "Video/RgbConversion.H"
00052 #include "Video/VideoFrame.H"
00053 #include "Util/MathFunctions.H"
00054 
00055 // ######################################################################
00056 static int submain(const int argc, char** argv)
00057 {
00058   MYLOGVERB = LOG_INFO;  // suppress debug messages
00059 
00060   // Instantiate a ModelManager:
00061   ModelManager manager("Psycho test timing");
00062 
00063   OModelParam<std::string> itsPort(&OPT_EyeTrackerParDev, &manager);
00064   
00065   nub::soft_ref<EventLog> el(new EventLog(manager));
00066   manager.addSubComponent(el);
00067   
00068   nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00069   manager.addSubComponent(d);
00070 
00071   nub::soft_ref<ParPort> itsParPort(new ParPort(manager, "Parallel Port", "ParPort"));
00072 
00073   itsParPort->setModelParamVal("ParPortDevName", itsPort.getVal());  
00074   
00075   manager.addSubComponent(itsParPort);
00076   
00077   manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy");
00078   
00079   // Parse command-line:
00080   if (manager.parseCommandLine(argc, argv,"<xpos> <ypos> <use par> <period in frames> <1=vsync> <1=hard sleep> <1=blink>",7,7)==false)
00081     return(1);
00082   
00083   // hook our various babies up and do post-command-line configs:
00084   d->setEventLog(el);
00085   d->setModelParamVal("PsychoDisplayBackgroundColor", PixRGB<byte>(0,0,0));
00086   
00087   // let's get all our ModelComponent instances started:
00088   manager.start();
00089   
00090   //stimulus position and size
00091   const int w = d->getDims().w(), h = d->getDims().h();
00092   const int fixrad = w / 100;
00093   const int siz2 = (fixrad - 1) / 2; // half cross size
00094   const int i = fromStr<int>(manager.getExtraArg(0));
00095   const int j = fromStr<int>(manager.getExtraArg(1));
00096 
00097   //make an image of our blank and target stimulus, convert our images
00098   //to yuv format and make a VideoFrame
00099   Rectangle rect = Rectangle::tlbrO(j - siz2, i - siz2, j + fixrad, i + fixrad);
00100   Image<PixRGB<byte> > itsStim(w, h, ZEROS);
00101   byte data[w*h + w*h/2];
00102   byte *y = &data[0], *u = &data[w*h], *v = &data[w*h + w*h/4];
00103   toVideoYUV422(itsStim, y, u, v);  
00104   VideoFrame blank = VideoFrame::deepCopyOf(VideoFrame(data, 
00105                                                        size_t(w*h + w*h/2), 
00106                                                        Dims(w,h), 
00107                                                        VIDFMT_YUV420P, 
00108                                                        false, true));
00109   
00110   drawFilledRect(itsStim, rect, PixRGB<byte>(255,255,255));  
00111   toVideoYUV422(itsStim, y, u, v);
00112   VideoFrame vid(data, size_t(w*h + w*h/2), Dims(w,h), 
00113                  VIDFMT_YUV420P, false, true);
00114 
00115   //create YUV overlay
00116   d->createVideoOverlay(VIDFMT_YUV420P, w, h);
00117 
00118   //grab some command line data  
00119   const bool usepar = fromStr<bool>(manager.getExtraArg(2));
00120   const int time = fromStr<int>(manager.getExtraArg(3));
00121   const bool vsync = fromStr<bool>(manager.getExtraArg(4));
00122   const bool hardwait = fromStr<bool>(manager.getExtraArg(5));
00123   const bool blink = fromStr<bool>(manager.getExtraArg(6));
00124   int frame = 0;
00125   int ltime = time;
00126   if (blink)
00127     ltime = time/2;
00128 
00129   //loop until key is hit
00130   if (usepar)
00131     itsParPort->WriteData(255, 0); //  strobe off
00132 
00133   while ((int)d->checkForKey() != 32)
00134     {
00135       //clear screen and sleep
00136       for (int ii = 0; ii < time; ++ii)
00137         {
00138           if (vsync)
00139             d->displayVideoOverlay(blank, frame, SDLdisplay::NEXT_VSYNC);
00140           else
00141             d->displayVideoOverlay(blank, frame, SDLdisplay::NO_WAIT);
00142           ++frame;
00143         }
00144 
00145       //hard wait here if if requested
00146       if (hardwait)
00147         d->waitForKey();
00148 
00149       //write log and pulse the parallel port
00150       if (usepar)
00151         {
00152           d->pushEventBegin("Parallel Port pulse");
00153           itsParPort->WriteData(255, 255); // strobe on
00154           itsParPort->WriteData(255, 0); //  strobe off
00155           d->pushEventEnd("Parallel Port pulse");
00156         }
00157       
00158       //display stimulus and leave on for 1/2 period
00159       for (int ii = 0; ii < ltime; ++ii)
00160         {
00161           if (vsync)
00162             d->displayVideoOverlay(vid, frame, SDLdisplay::NEXT_VSYNC);
00163           else
00164             d->displayVideoOverlay(vid, frame, SDLdisplay::NO_WAIT);
00165           ++frame;
00166           
00167           if (blink)
00168             {
00169               if (vsync)
00170                 d->displayVideoOverlay(blank, frame, SDLdisplay::NEXT_VSYNC);
00171               else
00172                 d->displayVideoOverlay(blank, frame, SDLdisplay::NO_WAIT);
00173               ++frame;
00174             }
00175         }
00176     }
00177   d->destroyYUVoverlay();
00178   // stop all our ModelComponents
00179   manager.stop();
00180   
00181   // all done!
00182   return 0;
00183 }
00184 
00185 // ######################################################################
00186 extern "C" int main(const int argc, char** argv)
00187 {
00188   // simple wrapper around submain() to catch exceptions (because we
00189   // want to allow PsychoDisplay to shut down cleanly; otherwise if we
00190   // abort while SDL is in fullscreen mode, the X server won't return
00191   // to its original resolution)
00192   try
00193     {
00194       return submain(argc, argv);
00195     }
00196   catch (...)
00197     {
00198       REPORT_CURRENT_EXCEPTION;
00199     }
00200   
00201   return 1;
00202 }
00203 
00204 // ######################################################################
00205 /* So things look consistent in everyone's emacs... */
00206 /* Local Variables: */
00207 /* indent-tabs-mode: nil */
00208 /* End: */
Generated on Sun May 8 08:40:10 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3