test-EphysAudio.C

Go to the documentation of this file.
00001 /*!@file AppDevices/test-EphysAudio.C Test ephys board programmed as USB input audio device */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Farhan Baluch <fbaluch@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppDevices/test-EphysAudio.C $
00035 // $Id: $
00036 //
00037 
00038 #include "Audio/AudioWavFile.H"
00039 #include "Component/ModelManager.H"
00040 #include "Devices/AudioGrabber.H"
00041 #include "Devices/AudioMixer.H"
00042 #include "GUI/XWindow.H"
00043 #include "Image/DrawOps.H"
00044 #include "Image/Image.H"
00045 #include "Util/log.H"
00046 #include "Util/sformat.H"
00047 #include "Util/Timer.H"
00048 #include <cstdio>
00049 #include <signal.h>
00050 #include <queue>
00051 #include <fstream>
00052 
00053 static bool goforever = true;  //!< Will turn false on interrupt signal
00054 #define SCALE 4
00055 
00056 std::queue<AudioBuffer<uint16> > rec;
00057 std::queue<AudioBuffer<uint16> > dispQ;
00058 pthread_mutex_t qmutex_data;
00059 pthread_mutex_t qmutex_disp;
00060 
00061 std::vector<AudioBuffer<uint16> > rec2;
00062 
00063 uint nsamples;
00064 int totalSamps=0;
00065 int numBuffs=0;
00066 int nChans =0;
00067 Timer tim; 
00068 
00069 //! Signal handler (e.g., for control-C)
00070 void terminate(int s) { LERROR("*** INTERRUPT ***"); goforever = false; }
00071 
00072 //##############################################################
00073 
00074 //! save data as it becomes available
00075 static void* saveData(void*)
00076 {
00077   std::ofstream outFile("ephys.dat");
00078   
00079   bool hadStuff = false;
00080   AudioBuffer<uint16> buf;
00081 
00082   while(goforever)
00083     {
00084       pthread_mutex_lock(&qmutex_data);
00085       if(rec.size())
00086         {
00087           buf = rec.front();
00088           rec.pop();
00089           hadStuff = true;       
00090         }
00091       
00092       pthread_mutex_unlock(&qmutex_data);
00093       
00094       
00095       if (hadStuff)
00096         {
00097           //fill display queue
00098           pthread_mutex_lock(&qmutex_disp);
00099           dispQ.push(buf);
00100           pthread_mutex_unlock(&qmutex_disp);
00101           
00102           numBuffs++;
00103           for (uint i=0; i < buf.nsamples(); i++)
00104           {
00105             totalSamps++;
00106             for (int c=0; c < nChans;c++)
00107                 outFile << (buf.getVal(i,c))*(4.096F/65536) << "\t ";
00108             outFile << std::endl;                          
00109           }
00110           hadStuff = false;
00111         }
00112     }
00113     outFile.close();
00114   return NULL;
00115 }
00116 //##############################################################
00117 
00118 //!plot the result
00119 static void* plotData(void*)
00120 {
00121     // draw the buffer into the image:
00122   int plotHeight = 128;
00123   XWindow win(Dims(nsamples, plotHeight * nChans),
00124                  -1, -1, "test-audioGrab window");
00125   Image<byte> ima(nsamples, plotHeight*nChans, NO_INIT);
00126     
00127   Point2D<int> p1, p2;
00128  
00129   bool hasStuff = false;
00130   AudioBuffer<uint16> buffer;
00131   while (goforever)
00132     {
00133       ima.clear();
00134       pthread_mutex_lock(&qmutex_disp);
00135       if(dispQ.size())
00136         {       
00137           buffer = dispQ.front();
00138           dispQ.pop();
00139           hasStuff = true;
00140         }
00141       pthread_mutex_unlock(&qmutex_disp);
00142       if(hasStuff)   
00143         {
00144           for (int c=0; c < nChans; c++)
00145             for (uint i = 1; i < nsamples; i ++)
00146               {
00147                 float val = (buffer.getVal(i,c))*(4.096F/65536);
00148                 float val1 = (buffer.getVal(i-1,c))*(4.096F/65536);
00149                 
00150                 float factor=plotHeight/4.096F;
00151                 p1.i = i - 1;
00152                 p1.j = plotHeight*(c+1) - val1*factor;
00153                 p2.i = i;
00154                 p2.j = plotHeight*(c+1) - val*factor;
00155                 
00156                 writeText(ima,Point2D<int>(4,plotHeight*(c+1)-plotHeight-5),
00157                           sformat("%f %f",val,tim.getSecs()).c_str());
00158                 drawLine(ima, p1, p2, byte(255));
00159               } 
00160           hasStuff = false;
00161         }
00162       win.drawImage(ima);
00163     }
00164 
00165   return NULL;
00166   }
00167 //##############################################################
00168 
00169 //! main
00170 int main(int argc, const char **argv)
00171 {
00172   // setup signal handling:
00173   signal(SIGHUP, terminate); signal(SIGINT, terminate);
00174   signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00175 
00176   // Instantiate a ModelManager:
00177   ModelManager manager("Test Model for AudioGrabber Class");
00178 
00179   // Instantiate our various ModelComponents:
00180   nub::soft_ref<AudioMixer> mix(new AudioMixer(manager));
00181   manager.addSubComponent(mix);
00182 
00183   nub::soft_ref<AudioGrabber> agb(new AudioGrabber(manager));
00184   manager.addSubComponent(agb);
00185 
00186   // Parse command-line:
00187   if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00188 
00189   // Let's get some of the option values, to configure our window:
00190   nsamples = agb->getModelParamVal<uint>("AudioGrabberBufSamples");
00191   nChans = agb->getModelParamVal<uint>("AudioGrabberChans");
00192   
00193  
00194   // let's get all our ModelComponent instances started:
00195   manager.start();
00196 
00197   pthread_t acqThread;
00198   pthread_t dispThread;
00199 
00200   int rc;
00201   rc = pthread_create(&acqThread,NULL,&saveData,NULL);
00202   if(rc)                        
00203     LFATAL("\n ERROR: return code from pthread_create is %d \n", rc);
00204   
00205   LINFO("\n Created new acquisition thread (%d) ... \n", (int)acqThread);
00206   int dt;
00207   dt = pthread_create(&dispThread,NULL,&plotData,NULL);
00208   if(dt)                        
00209     LFATAL("\n ERROR: return code from pthread_create is %d \n", dt);
00210   
00211   LINFO("\n Created new display thread (%d) ... \n", (int)dispThread);
00212 
00213   
00214   tim.reset();
00215   
00216   // main loop:
00217   while(goforever) {
00218 
00219     // grab a buffer:
00220     AudioBuffer<uint16> buffer;
00221     agb->grab(buffer);
00222     // LINFO("Buff size: %d",buffer.size());
00223     
00224     pthread_mutex_lock(&qmutex_data);
00225     rec.push(buffer);
00226     pthread_mutex_unlock(&qmutex_data);
00227     
00228     rec2.push_back(buffer);
00229         
00230     if(tim.getSecs()>=5)
00231       goforever =false;
00232 
00233   }
00234 
00235   LINFO("writing out audio file: testAudio.wav");
00236   LINFO("Num buffs processed %d",numBuffs);
00237   // save our current records
00238   writeAudioWavFile("testAudio.wav", rec2);
00239 
00240   // stop all our ModelComponents
00241   manager.stop();
00242 
00243   // all done!
00244   return 0;
00245 }
00246 
00247 // ######################################################################
00248 /* So things look consistent in everyone's emacs... */
00249 /* Local Variables: */
00250 /* indent-tabs-mode: nil */
00251 /* End: */
Generated on Sun May 8 08:04:10 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3