00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "Component/ModelManager.H"
00038 #include "Image/Image.H"
00039 #include "Psycho/PsychoDisplay.H"
00040 #include "Psycho/EyeTrackerConfigurator.H"
00041 #include "Psycho/EyeTracker.H"
00042 #include "Psycho/PsychoOpts.H"
00043 #include "Component/EventLog.H"
00044 #include "Component/ComponentOpts.H"
00045 #include "Raster/Raster.H"
00046 #include "Util/MathFunctions.H"
00047 #include "Util/Types.H"
00048 #include "GameBoard/basic-graphics.H"
00049 #include <sys/types.h>
00050 #include <dirent.h>
00051 #include <errno.h>
00052 #include <vector>
00053 #include <string>
00054 #include <iostream>
00055 #include <SDL/SDL.h>
00056 #include <SDL/SDL_image.h>
00057 #include <SDL/SDL_mixer.h>
00058 #include <stdio.h>
00059 #include <stdlib.h>
00060 #include <sstream>
00061 #include <time.h>
00062 #include "Image/DrawOps.H"
00063 #include "GameBoard/resize.h"
00064 #include <iostream>
00065 #include <fstream>
00066 #include <set>
00067 #include <algorithm>
00068 #include <ctime>
00069
00070 #ifndef INVT_HAVE_LIBSDL_IMAGE
00071 #include <cstdio>
00072 int main()
00073 {
00074 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00075 return 1;
00076 }
00077
00078 #else
00079
00080
00081
00082 using namespace std;
00083
00084
00085
00086 ModelManager manager("psycho-wm-chunking");
00087 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00088 map<uint,uint> testMap ;
00089 map<string,string> argMap ;
00090 map<string,vector<SDL_Rect*>*> clipsmap;
00091
00092
00093
00094
00095 template <class T> std::string stringify(T i)
00096 {
00097 ostringstream o ;
00098 o << i ;
00099 return o.str();
00100 }
00101
00102 bool itIsInThere(int x , vector<int> bag){
00103 for( uint i=0 ; i < bag.size(); i++ ){
00104 if(x == bag[i]) return true ;
00105 }
00106 return false ;
00107 }
00108
00109
00110
00111
00112
00113
00114 void scramble(vector<int>& v){
00115 vector<int> tv = vector<int>() ;
00116 while(v.size()>0){
00117 tv.push_back(v[0]);
00118 v.erase(v.begin());
00119 }
00120 int i = 0 ;
00121 while(tv.size()>0){
00122 i = rand()%tv.size() ;
00123 v.push_back(tv[i]);
00124 tv.erase(tv.begin()+i);
00125 }
00126 }
00127
00128
00129
00130
00131 int getdir (string dir, vector<string> &files)
00132 {
00133 DIR *dp;
00134 struct dirent *dirp;
00135 if((dp = opendir(dir.c_str())) == NULL) {
00136 cout << "Error(" << errno << ") opening " << dir << endl;
00137 return errno;
00138 }
00139 string fn = "" ;
00140 size_t found;
00141 string extension = "" ;
00142 while ((dirp = readdir(dp)) != NULL) {
00143 fn = string(dirp->d_name) ;
00144 found = fn.find_last_of(".");
00145 if(found > 0 && found <1000){
00146 extension = fn.substr(found) ;
00147 if(extension.compare(".wav")== 0 )
00148 files.push_back(dir+"/"+fn);
00149 }
00150 }
00151 closedir(dp);
00152 return 0;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162 int addArgument(const string st,const string delim="="){
00163 int i = st.find(delim) ;
00164 argMap[st.substr(0,i)] = st.substr(i+1);
00165
00166 return 0 ;
00167 }
00168
00169 std::string getArgumentValue(string arg){
00170 return argMap[arg] ;
00171 }
00172
00173 std::vector<int> getDigits(int n , string zs="n" , string rs="n" ){
00174 if(rs.compare("n")==0){
00175 if(zs.compare("n")==0 && n >9 ) {LINFO( "come on! what do you expect?!") ; exit(-1) ;}
00176 if(zs.compare("y")==0 && n >10 ) {LINFO( "come on! what do you expect?!") ; exit(-1) ;}
00177 }
00178 vector<int> digits ;
00179 int dig = 0 ;
00180 while( digits.size() < (uint)n ){
00181 if(zs.compare("n")==0) {dig = 1+(random()%9);}else{dig = random()%10;}
00182 if(rs.compare("y")==0){digits.push_back(dig);}else{if(!itIsInThere(dig,digits)) digits.push_back(dig);}
00183 }
00184 return digits ;
00185 }
00186
00187 std::string getUsageComment(){
00188
00189 string com = string("\nlist of arguments : \n");
00190
00191 com += "\nlogfile=[logfilename.psy] {default = psycho-wm-chunking.psy}\n" ;
00192 com += "\nmemo=[a_string_without_white_space]\n";
00193 com += "\nnum-of-digits=[>0](the size of string){default=3} \n";
00194 com += "\nsubject=[subject_name] \n" ;
00195 com += "\nseperate-recall-rounds=[>1] (number of trials including seperate recall task ) {default=2}\n";
00196 com += "\nfirst-to-last-rounds=[>1](number of trials including first to last chunking){default=2}}\n";
00197 com += "\nlast-to-first-rounds=[>1](number of trials including last to firts chunking){default=2}}\n";
00198 com += "\nalphabet=[a string of characters](a string of characters){default=0123456789}\n";
00199 com += "\ncue-wait-frames=[>0](number of frames to show the cue){default=0}\n";
00200 com += "\ncue-onset-frames=[>0](number of frames to show the cue onset){default=10}\n";
00201 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00202 com += "\ndigit-repeat=[y/n](whether digits can repeat, y for yes , n for no){default=n}\n" ;
00203 com += "\ninclude-zero=[y/n](whether zero be included in the presented digits, y for yes , n for no){default=n}\n";
00204 com += "\ndelay=[>1] (delay in number of frames in which recording happens)\n" ;
00205 return com ;
00206 }
00207
00208
00209 extern "C" int main(const int argc, char** argv)
00210 {
00211
00212 MYLOGVERB = LOG_INFO;
00213
00214 argMap["experiment"]="chunking firs to last, chunking last to first and no chunking";
00215 argMap["logfile"]="psycho-wm-chunking.psy" ;
00216 argMap["num-of-digits"]="3" ;
00217 argMap["seperate-recall-rounds"]="2";
00218 argMap["first-to-last-rounds"] = "2" ;
00219 argMap["last-to-first-rounds"] = "2" ;
00220 argMap["subject"]="" ;
00221 argMap["memo"]="" ;
00222 argMap["alphabet"]="0123456789";
00223 argMap["cue-wait-frames"]="0" ;
00224 argMap["cue-onset-frames"] = "10" ;
00225 argMap["sound-dir"]="..";
00226 argMap["include-zero"]="n";
00227 argMap["digit-repeat"]="n" ;
00228 argMap["delay"] = "120" ;
00229
00230 manager.addSubComponent(d);
00231 nub::soft_ref<EventLog> el(new EventLog(manager));
00232 manager.addSubComponent(el);
00233 d->setEventLog(el);
00234 nub::soft_ref<EyeTrackerConfigurator>
00235 etc(new EyeTrackerConfigurator(manager));
00236 manager.addSubComponent(etc);
00237
00238 if (manager.parseCommandLine(argc, argv,
00239 "at least one argument needed", 1, -1)==false){
00240 cout<<getUsageComment()<<endl;
00241 return(1);
00242 }
00243
00244 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00245 addArgument(manager.getExtraArg(i),std::string("=")) ;
00246 }
00247
00248 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00249 manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00250 nub::soft_ref<EyeTracker> eyet = etc->getET();
00251 d->setEyeTracker(eyet);
00252 eyet->setEventLog(el);
00253
00254
00255 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00256 LINFO( "did not open the mix-audio") ;
00257 return -1 ;
00258 }
00259
00260 map<int,Mix_Music*> audioMap ;
00261 for( int i = 0 ; i < 10 ; i++ ){
00262 string str = argMap["sound-dir"]+"/"+stringify(i)+".wav" ;
00263 audioMap[i] = Mix_LoadMUS(str.c_str());
00264 }
00265 int delay = atoi(argMap["delay"].c_str()) ;
00266 int numOfDigits = atoi(argMap["num-of-digits"].c_str());
00267 int cue_onset_frames = atoi(argMap["cue-onset-frames"].c_str()) ;
00268 int cue_wait_frames = atoi(argMap["cue-wait-frames"].c_str()) ;
00269 int num_of_first_task = atoi(argMap["seperate-recall-rounds"].c_str());
00270 int num_of_second_task = atoi(argMap["first-to-last-rounds"].c_str());
00271 int num_of_third_task = atoi(argMap["last-to-first-rounds"].c_str());
00272 vector<int>* taskVector = new vector<int>();
00273 for(int i = 0 ; i < num_of_first_task ; i++) taskVector->push_back(1);
00274 for(int i = 0 ; i < num_of_second_task ; i++) taskVector->push_back(2);
00275 for(int i = 0 ; i < num_of_third_task ; i++) taskVector->push_back(3);
00276 scramble(*taskVector);
00277
00278
00279 manager.start();
00280 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00281
00282 d->clearScreen();
00283 d->displayISCANcalib();
00284 d->waitForMouseClick();
00285 d->displayText("Here the experiment starts! click to start!");
00286 d->waitForMouseClick();
00287 d->clearScreen();
00288
00289 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00290 int cl = d->waitForMouseClick();
00291 if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00292 d->clearScreen();
00293
00294 Uint32 fc = d->getUint32color(PixRGB<byte>(255,0,0));
00295 Uint32 sc = d->getUint32color(PixRGB<byte>(0,255,0));
00296 Uint32 tc = d->getUint32color(PixRGB<byte>(0,0,255));
00297 SDL_Surface* f_pad= getABlankSurface(36,34);
00298 SDL_Surface* s_pad= getABlankSurface(36,34);
00299 SDL_Surface* t_pad= getABlankSurface(36,34) ;
00300 fillRectangle(f_pad,fc,0,0,35 ,33);
00301 fillRectangle(s_pad,sc,0,0,35 ,33);
00302 fillRectangle(t_pad,tc,0,0,35 ,33);
00303 SDL_Rect cue_offset ;
00304 cue_offset.x = (d->getWidth() -36) /2;
00305 cue_offset.y = (d-> getHeight() - 34) /2;
00306 int fs = 0 ;
00307 int ss = 0;
00308 int ts = 0 ;
00309 for( uint r = 0 ; r < taskVector->size() ; r++ ){
00310 d->showCursor(true);
00311 d->displayText("click one of the mouse buttons to start!");
00312 d->waitForMouseClick() ;
00313 d->showCursor(false) ;
00314 d->clearScreen() ;
00315 d->displayFixationBlink();
00316 int task = taskVector->at(r) ;
00317 vector<int> digits = getDigits(numOfDigits,argMap["include-zero"],argMap["digit-repeat"]);
00318 int counter = 0 ;
00319 while( counter < numOfDigits ){
00320 if(Mix_PlayingMusic() == 0 ){
00321
00322 if( Mix_PlayMusic( audioMap[digits[counter]], 0 ) == -1 ) { return 1; }
00323 d->pushEvent("the "+stringify(counter)+"th : " +stringify(digits[counter]));
00324 counter++ ;
00325 }
00326 }
00327
00328 while( Mix_PlayingMusic() == 1 ){}
00329 if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00330 std::string imst = "===== Showing image: def";
00331 PixRGB<byte> cuecolor;
00332 switch( task ){
00333 case 1 : fs++ ; d->displaySDLSurfacePatch(f_pad , &cue_offset,NULL , -2,false, true); imst += "_first_"+stringify(fs)+".png" ; break ;
00334 case 2 : ss++ ; d->displaySDLSurfacePatch(s_pad , &cue_offset,NULL , -2,false, true);imst += "_second_"+stringify(ss)+".png" ;break ;
00335 case 3 : ts++ ; d->displaySDLSurfacePatch(t_pad , &cue_offset,NULL , -2,false, true);imst += "_third_" +stringify(ts)+".png";break ;
00336 }
00337
00338 d->pushEvent(imst);
00339 d->waitFrames(cue_onset_frames);
00340 eyet->track(true);
00341 d->clearScreen() ;
00342 d->waitFrames(delay);
00343 eyet->track(false);
00344 d->displayText("SAY THE NUMBER LOUD!");
00345 d->waitForMouseClick();
00346 d->pushEvent("**************************************") ;
00347 }
00348 d->clearScreen();
00349 d->displayText("Experiment complete. Thank you!");
00350 d->waitForMouseClick();
00351
00352
00353
00354 manager.stop();
00355
00356
00357 for( int i = 0 ; i < 10 ; i++ ){
00358 Mix_FreeMusic(audioMap[i]);
00359 }
00360
00361 Mix_CloseAudio();
00362
00363 return 0;
00364 }
00365
00366 #endif // INVT_HAVE_LIBSDL_IMAGE
00367