Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

MainDialog.cpp

Go to the documentation of this file.
00001 //
00002 // File: MainDialog.cpp
00003 // Created by: cc <cc@cmn42.Stanford.EDU>
00004 // Created on: Sun Mar  2 10:20:41 2003
00005 //
00006 
00007 #include "MainDialog.h"
00008 #include "qapplication.h"
00009 #include "qradiobutton.h"
00010 #include "qpushbutton.h"
00011 #include "qprogressbar.h"
00012 #include "qslider.h"
00013 #include "qaccel.h"
00014 #include "Jukebox.h"
00015 #include "Logger.h"
00016 using namespace std;
00017 #include <iostream>
00018 #include <vector>
00019 #include <algorithm>
00020 #include <time.h>
00021 #include <stdlib.h>
00022 
00023 extern Snd *theSnd;
00024 
00025 MainDialog::MainDialog (QWidget * parent, const char *name):
00026   MainForm (parent, name)               // generated by designer
00027 {
00028   juke = new Jukebox ();        // read in files, count 'em
00029   nTalk = juke->getNumTalkFiles() / CH;
00030   nMask = juke->getNumMaskFiles() / CH;
00031   independent_talk_conditions = nTalk-1;        
00032   nTrials = independent_talk_conditions * nMask;
00033   juke->setNumTrials(nTrials);
00034   cout << "nTrials = " << nTrials << endl;
00035   
00036   //=========================================================
00037   /*
00038     DEFINE HERE OUTPUT PATH and TEST NAME
00039     -------------------------------------
00040     TEST NAME Should have the Following Name Convension:
00041     exp#_subjID
00042     for example: experiment01_Subject01
00043     Don't Forget to define the names of the output files
00044     Use a different file name for each subject, and the same
00045     name for the experiment tipe.
00046     A Complete example will be:
00047     QString logRoot ("/zap/"); // output directory
00048     log = new Logger ("experiment01_Subject01", // ID
00049                       logRoot + "experiment01_Subject01.dat", // single subject file
00050                       logRoot + "experiment01.dat"      // all subjects file
00051     );
00052   */
00053 
00054   QString logRoot ("/zap/"); // output directory
00055   log = new Logger ("experiment01_Subject01",   // ID
00056                     logRoot + "experiment01_Subject01.dat", // single subject file
00057                     logRoot + "experiment01.dat"        // all subjects file
00058                     );
00059   //===========================================================
00060   
00061   mythreads.setAutoDelete (true);
00062   
00063   /* link threads to start / stop */
00064   addThread (theSnd, false);    // not a thread now that we're using jack
00065   
00066   /* add to orch */
00067   theSnd->addInstrument (juke);
00068   
00069   /* wire up the signals and slots */
00070   // GUI next pair
00071   connect ((QObject *) nextB, SIGNAL (clicked ()), this,
00072            SLOT (trialTick ()));
00073   // GUI stop playing
00074   connect ((QObject *) stopB, SIGNAL (clicked ()), juke,
00075            SLOT (stopPlay ()));
00076   // GUI play file A
00077   connect ((QObject *) AplayB, SIGNAL (clicked ()), juke,
00078            SLOT (playA ()));
00079   // GUI play file B
00080   connect ((QObject *) BplayB, SIGNAL (clicked ()), juke,
00081            SLOT (playB ()));
00082   // GUI show progress
00083   connect ((QObject *) juke, SIGNAL (updateProgress (int)), progressBar,
00084            SLOT (setProgress (int)));
00085   // quit from inside program
00086   connect ((QObject *) juke, SIGNAL (quitAll ()),
00087            qApp, SLOT (closeAllWindows ()));
00088   // GUI <ctrl>q 
00089   QAccel *a = new QAccel (this);
00090   a->connectItem (a->insertItem (Key_Q + CTRL),
00091                   qApp, SLOT (closeAllWindows ()));
00092   
00093   goThreads (true); // run
00094   
00095   
00096   /*JPa**************************************************************************** 
00097     Create vectores and shuffle them to use in the experiment
00098     This vectors will be shuffled once (here) and then is just reading them 
00099     The mothod is crating a vector of all the pair that will be tested, and then 
00100     shuffle that vector. For example:
00101     TalkMask_matrix[0] = [0,0]
00102     TalkMask_matrix[1] = [1,0]
00103     TalkMask_matrix[2] = [2,0]
00104     TalkMask_matrix[3] = [3,0]    
00105     TalkMask_matrix[4] = [0,1]
00106     TalkMask_matrix[5] = [1,1]
00107     TalkMask_matrix[6] = [2,1]
00108     TalkMask_matrix[7] = [3,1]
00109     and then we shuffle this TalkMask_matrix, so we are sure that each combination
00110     is represented.
00111   ******************************************************************************/
00112   vector<int> TalkMask(2,0); //creates a vector of 2 ints of value 0
00113   for (int i = 0; i < independent_talk_conditions*nMask; i++) {
00114     //TalkMask[0] = 1 + (i % independent_talk_conditions); //Talks counts [1,2,3,4,1,2,3,4,...]
00115     TalkMask[0] = (i % independent_talk_conditions); //Talks counts [0,1,2,3,0,1,2,3,...]
00116     TalkMask[1] = i/independent_talk_conditions; //Masks // counts [0,0,0,0,1,1,1,1,2,...]
00117     TalkMask_matrix.push_back(TalkMask);
00118   }
00119   srand (time(0)); // need to call srand to get a different arrangement each time the program is called
00120   random_shuffle(TalkMask_matrix.begin(), TalkMask_matrix.end()); //Shuffle matrix vector
00121   //*******************************************************************************
00122   
00123   curTrial = 0;
00124   setTrial (curTrial);
00125   
00126   juke->setTrial (curTrial, curTalk, curMask, silenceIsA); // set jukebox for trial
00127   //JPa**************************************************************************** 
00128   stopB->setChecked(true);
00129   //**********************************************************************8
00130   
00131 }
00132 
00133 void MainDialog::loggerTick ()
00134 {
00135   // silence is playing from button A and user selected button A
00136   bool inResult = (silenceIsA == AselectB->isChecked ());
00137   log->writeData (curTalk, curMask, inResult);
00138 }
00139 
00140 void MainDialog::trialTick ()
00141 {
00142   //JPa****************************************************************************
00143   if (!(AselectB->isChecked()) &&  !(BselectB->isChecked())) {
00144     cout << "Please Select One of the Options..." << endl;
00145   }
00146   //********************************************************************************
00147   else {
00148     loggerTick (); // log last response
00149     setTrial (++curTrial); // set trial params  ///HERE IS THE PROBLEM!!!!!!!!!!!!!!!!!!!
00150 
00151     //JPa***************************************************************************
00152     juke->stopPlay(); //stop playbck of noises in new trial
00153     //***************************************************************
00154     juke->setTrial (curTrial, curTalk, curMask, silenceIsA); // set jukebox for trial
00155     
00156     //JPa***************************************************************************
00157     //Un-check all radio buttons when user presses next
00158     //I couldn't find a better way to do this (it was painful...)
00159     stopB->setChecked(true); // check stop button, since the sounds are stoping in the new trial
00160     AselectB->setChecked(false);
00161     BselectB->setChecked(false);
00162     AplayB->setChecked(false);
00163     BplayB->setChecked(false);
00164     //*******************************************************************************
00165   }
00166 }
00167 
00168 void MainDialog::setTrial (int n)
00169 {       
00170   //  cout << "CACACACACA" << endl;
00171   if (n == nTrials)
00172     cout << "DONE " << endl;
00173   else {
00174     //JPa ******************************************************************************
00175     vector<int> aux_talkmask = TalkMask_matrix[n];
00176     curTalk = aux_talkmask[0];
00177     curMask = aux_talkmask[1];
00178     //**********************************************************************************
00179     
00180     //curTalk = 1 + (n % independent_talk_conditions); // counts [1,2,3,4,1,2,3,4,...]
00181     //curMask = n/independent_talk_conditions; // counts [0,0,0,0,1,1,1,1,2,...]
00182     
00183     //silenceIsA = true;
00184     
00185     //JPa ******************************************************************************
00186     //Fix silenceIsA to a random true or false
00187     srand( (unsigned)time( NULL ) );
00188     silenceIsA = rand() % 2; //Random number 0 or 1    
00189     //**********************************************************************************
00190     //cout << "TRIAL " << curTrial << " (" << curTalk << ", " << curMask << ", " << silenceIsA <<")" << endl;
00191   }
00192 }
00193 
00194 MainDialog::~MainDialog ()
00195 {
00196   //cout << "DESTRUCTOR" << endl;
00197   //delete juke;
00198   delete log;
00199 }
00200 
00201 void MainDialog::goThreads (bool go)
00202 {
00203   if (go)
00204     {
00205       emit startThread ();
00206     }
00207   else
00208     {
00209       emit stopThread ();
00210       emit joinThread ();
00211     }
00212 }
00213 
00214 void MainDialog::addThread (QObject * t, bool isThread)
00215 /* append thread to mythreads list */
00216 {
00217   mythreads.append (t);
00218   connect (this, SIGNAL (startThread ()), t, SLOT (go ()));
00219   connect (this, SIGNAL (stopThread ()), t, SLOT (stop ()));
00220   if (isThread)
00221     connect (this, SIGNAL (joinThread ()), t, SLOT (join ()));
00222 }
00223 
00224 void MainDialog::closeEvent (QCloseEvent * e)
00225 {
00226   if (mythreads.count ())
00227     goThreads (false);
00228   jack->stop ();
00229   while (qApp->hasPendingEvents ())
00230     qApp->processEvents ();
00231   e->accept ();
00232 }
00233 
00234 void MainDialog::customEvent (QCustomEvent * e)
00235 {
00236   if (e->type () == QEvent::User + 117)
00237     /* received from xxx */
00238     {
00239       ThreadCommEvent *ce = (ThreadCommEvent *) e;
00240       //      yyy (ce->val0 (), ce->val1 (),  ce->val2 ());
00241     }
00242 }
00243 
00247 int get_fifo_priority (bool notMax)
00248 {
00249   int min, max, priority;
00250   
00251   min = sched_get_priority_min (SCHED_FIFO);
00252   max = sched_get_priority_max (SCHED_FIFO);
00253   if (notMax)
00254     priority = min + (max - min) / 2;
00255   else
00256     priority = max;
00257   //      priority=min;
00258   return priority;
00259 }
00260 
00264 int set_fifo_priority (bool half)
00265 {
00266   struct sched_param p;
00267   int priority;
00268   //  scheduling priority
00269   
00270   
00271   if (true)             // (!getuid () || !geteuid ())
00272     {
00273       priority = get_fifo_priority (half);
00274       p.sched_priority = priority;
00275       
00276       if (sched_setscheduler (0, SCHED_FIFO, &p) == -1)
00277         {
00278           fprintf (stderr,
00279                    "\ncould not activate scheduling with priority %d\n",
00280                    priority);
00281           return -1;
00282         }
00283       seteuid (getuid ());
00284       //                fprintf (stderr,
00285       //                         "\nset scheduling priority to %d (SCHED_FIFO)\n",
00286       //                         priority);
00287     }
00288   else
00289     {
00290       fprintf (stderr,
00291                "\ninsufficient privileges to set scheduling priority\n");
00292       priority = 0;
00293     }
00294   return priority;
00295 }

Generated on Thu Aug 3 16:14:47 2006 by  doxygen 1.4.4