Haptic metronome, speed accuracy track generation
authorThomas Pietrzak <thomas.pietrzak@gmail.com>
Fri, 27 May 2011 21:10:20 +0000 (21:10 +0000)
committerThomas Pietrzak <thomas.pietrzak@gmail.com>
Fri, 27 May 2011 21:10:20 +0000 (21:10 +0000)
git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@17 47cf9a05-e0a8-4ed5-9e9b-101a649bc004

13 files changed:
Haptic Metronome/Haptic Metronome.suo
include/Config.hpp
include/Mixer.hpp
include/Serial.hpp
include/SerialWindows.hpp
include/Track.hpp
src/Config.cpp
src/MetronomeHaptic.cpp
src/Mixer.cpp
src/PaintGame.cpp
src/SerialWindows.cpp
src/Track.cpp
src/main.cpp

index d2e0b3597d8d7369693f48d36ba97919d122e037..8e8eb835a6076069edf1f2140bcf3a3c5d669745 100644 (file)
Binary files a/Haptic Metronome/Haptic Metronome.suo and b/Haptic Metronome/Haptic Metronome.suo differ
index d208ec12e81c845ccb09a96b4a0494cdf24a122d..54d0e54b7ed7c915593a65c1a1cac41485d15dd4 100644 (file)
@@ -26,7 +26,9 @@ using namespace std;
 class Config
 {
        public:
-               Config(uint32_t timestamp=0, uint32_t end=0, uint32_t time=0, uint32_t ticks=0,
+               Config(uint8_t buttons, uint32_t timestamp=0, uint32_t endtimestamp=0, uint32_t time=0, uint32_t ticks=0);
+
+               Config(uint32_t timestamp=0, uint32_t endtimestamp=0, uint32_t time=0, uint32_t ticks=0,
                        bool a=false, bool b=false, bool c=false, bool d=false, bool e=false);
 
                Config(const Config &cf);
index ba49c2e1bc6c2190a80303c2d61ddd3339c3f1e3..512b3b24b898040c46304eccf3047deca076e096 100644 (file)
@@ -40,15 +40,16 @@ class Mixer
   public:
     Mixer();
     ~Mixer();
-    static void playMusic(const String &);
+    static void loadMusic(const String &);
+    static void playMusic();
     static void stopMusic();
     void playSound(const String &);
     void stopSound(const int &);
     bool addSound(const String &s, const String &filename);
     static void channelStopped(int);
-               int getMusicVolume() const { return _musicVolume; }
+       int getMusicVolume() const { return _musicVolume; }
     void setMusicVolume(const int &);
-               int getSoundVolume() const { return _soundVolume; }
+       int getSoundVolume() const { return _soundVolume; }
     void setSoundVolume(const int &);
   
     static void initMixer();
index 096fe6fa7357570ec02fecea5b8baf1111551efb..f306af78f1f37fc405e1d950e40ae29ce6212e84 100644 (file)
@@ -18,11 +18,11 @@ class Serial
         //maximum number of bytes available, it will return only the\r
         //bytes available. The function return -1 when nothing could\r
         //be read, the number of bytes actually read.\r
-        virtual int ReadData(char *buffer, unsigned int nbChar)=0;\r
+        virtual int ReadData(void *buffer, unsigned int nbChar)=0;\r
 \r
         //Writes data from a buffer through the Serial connection\r
         //return true on success.\r
-        virtual bool WriteData(char *buffer, unsigned int nbChar)=0;\r
+        virtual bool WriteData(void *buffer, unsigned int nbChar)=0;\r
 \r
         //Check if we are actually connected\r
                bool IsConnected() { return _connected; }\r
index 3b99741d8b43311b70654e937a40f68421ede643..28eb1af480fc2d6bf7706904b5bbdbdca9787d9c 100644 (file)
@@ -18,10 +18,10 @@ class SerialWindows : public Serial
         //maximum number of bytes available, it will return only the\r
         //bytes available. The function return -1 when nothing could\r
         //be read, the number of bytes actually read.\r
-        int ReadData(char *buffer, unsigned int nbChar);\r
+        int ReadData(void *buffer, unsigned int nbChar);\r
         //Writes data from a buffer through the Serial connection\r
         //return true on success.\r
-        bool WriteData(char *buffer, unsigned int nbChar);\r
+        bool WriteData(void *buffer, unsigned int nbChar);\r
 \r
 \r
     private:\r
index c5679f6aa86afd607628414b5b2a312cb2cd5cd6..efcc702eea82ea6eccfadfd706e2a235e8f949b4 100644 (file)
@@ -42,6 +42,8 @@ class Track
     Track(const Track &);
        //create an empty track with the specified tempo and specified duration
     Track(uint32_t tempo, uint32_t duration);
+       //create a track for speed/accuracy experiments
+    Track(uint8_t nbbuttons, uint8_t repetitions, uint8_t nbspeeds, uint32_t *speeds);
     ~Track();
 
     void addKey(uint32_t time, uint8_t note);
index ebe8ea8be3aaa8920d6f6f87a76522c4e0b0f66f..fd0bb7e55a1f9417368350be28ac0d0b3ef66f97 100644 (file)
@@ -9,6 +9,12 @@ Config::Config(uint32_t timestamp, uint32_t endtimestamp, uint32_t time, uint32_
 {
 }
 
+Config::Config(uint8_t buttons, uint32_t timestamp, uint32_t endtimestamp, uint32_t time, uint32_t ticks)
+:_timestamp(timestamp), _endtimestamp(endtimestamp), _time(time), _ticks(ticks), 
+_a(buttons & 0x01), _b((buttons >> 1) & 0x01), _c((buttons >> 2) & 0x01), _d((buttons >> 3) & 0x01), _e((buttons >> 4) & 0x01)
+{
+}
+
 Config::Config(const Config &cf)
 :_timestamp(cf._timestamp), _endtimestamp(cf._endtimestamp), _time(cf._time), _ticks(cf._ticks), 
        _a(cf._a), _b(cf._b), _c(cf._c), _d(cf._d), _e(cf._e)
index 91af41dead35aee67d0a934ae6ee545c3a04f0c2..30c1c932aff5f9e63f40ab3f82e8dc5fd680be65 100644 (file)
     extern struct timeval start;
 #endif
 
-#define BEFOREDELAY 150
+#define BEFOREDELAY 2000
 
 extern FILE *logfile;
 
 MetronomeHaptic::MetronomeHaptic(const Track *track, uint32_t nbbeats, uint32_t tempo, bool activated)
-:Metronome(track, nbbeats, tempo, activated), thread(NULL), _comport(new SerialWindows("COM5"))
+:Metronome(track, nbbeats, tempo, activated), thread(NULL), _comport(new SerialWindows("COM3"))
 {
+       unsigned char buffer1[3];\r
+       buffer1[0] = 'N'; buffer1[1] = 0x00; buffer1[2] = 0x01;\r
+       unsigned char buffer2[6];\r
+       buffer2[0] = 0x01;                                      //pattern\r
+       buffer2[1] = 0; buffer2[2] = 100;       //duration\r
+       buffer2[3] = 0; buffer2[4] = 250;       //frequency\r
+       buffer2[5] = 255;                                       //amplitude\r
+\r
+       //Tacton 1\r
+       _comport->WriteData(buffer1, 3);
+       _comport->WriteData(buffer2, 6);
+\r
+/*     char INBUFFER[128];\r
+       memset(INBUFFER, 0, 128);
+       int nbread = _comport->ReadData(INBUFFER, 128);
+       stringstream s;
+       s << nbread << " read:\n" << INBUFFER << endl;
+       OutputDebugString(s.str().c_str());*/\r
+       \r
+       //Tacton 2\r
+       buffer2[0] = 0x02;                                      //pattern\r
+       _comport->WriteData(buffer1, 3);
+       _comport->WriteData(buffer2, 6);
+
+/*     memset(INBUFFER, 0, 128);
+       nbread = _comport->ReadData(INBUFFER, 128);
+       stringstream s2;
+       s2 << nbread << " read:\n" << INBUFFER << endl;
+       OutputDebugString(s2.str().c_str());*/
+       \r
+       //Tacton 3\r
+       buffer2[0] = 0x04;                                      //pattern\r
+       _comport->WriteData(buffer1, 3);
+       _comport->WriteData(buffer2, 6);
+       
+/*     memset(INBUFFER, 0, 128);
+       nbread = _comport->ReadData(INBUFFER, 128);
+       stringstream s3;
+       s3 << nbread << " read:\n" << INBUFFER << endl;
+       OutputDebugString(s3.str().c_str());*/
+       
+       //Tacton 4\r
+       buffer2[0] = 0x08;                                      //pattern\r
+       _comport->WriteData(buffer1, 3);
+       _comport->WriteData(buffer2, 6);
+
+/*     memset(INBUFFER, 0, 128);
+       nbread = _comport->ReadData(INBUFFER, 128);
+       stringstream s4;
+       s4 << nbread << " read:\n" << INBUFFER << endl;
+       OutputDebugString(s4.str().c_str());*/
 }
 
 MetronomeHaptic::~MetronomeHaptic()
 {
+       _comport->WriteData("Q", 1);
        _activated = false;
        delete _comport;
        SDL_WaitThread(thread, NULL);
@@ -34,9 +86,9 @@ void MetronomeHaptic::setTempo(uint32_t tempo)
        Metronome::setTempo(tempo);\r
        //send info to Serial Port\r
        //char outBuffer[5];\r
-       char outBuffer[5];// = {'T', 'A', 'B', 'C', 'D'};\r
+       /*char outBuffer[5];// = {'T', 'A', 'B', 'C', 'D'};\r
        memset(outBuffer, 0, 5);
-       /*sprintf(OUTBUFFER, "T%3d\n", 60000000/tempo);*/\r
+       sprintf(OUTBUFFER, "T%3d\n", 60000000/tempo);\r
        outBuffer[0] = 'T';\r
        outBuffer[1] = (tempo & 0xff000000) >> 24;\r
        outBuffer[2] = (tempo & 0x00ff0000) >> 16;\r
@@ -44,7 +96,7 @@ void MetronomeHaptic::setTempo(uint32_t tempo)
        outBuffer[4] = tempo & 0x000000ff;\r
        
        bool written = _comport->WriteData(outBuffer, 5);\r
-       /*
+       
        char INBUFFER[128];\r
        memset(INBUFFER, 0, 128);
        int nbread = _comport->ReadData(INBUFFER, 128);
@@ -57,9 +109,9 @@ void MetronomeHaptic::setNbBeats(uint32_t nbbeats)
 {
        Metronome::setNbBeats(nbbeats);\r
        //send info to Serial Port\r
-       char outBuffer[5];// = {'B', '5', '6', '7', '8'};\r
+/*     char outBuffer[5];// = {'B', '5', '6', '7', '8'};\r
        memset(outBuffer, 0, 5);
-/*     sprintf(OUTBUFFER, "B%3d\n", nbbeats);*/\r
+       sprintf(OUTBUFFER, "B%3d\n", nbbeats);\r
        outBuffer[0] = 'B';\r
        outBuffer[1] = (nbbeats & 0xff000000) >> 24;\r
        outBuffer[2] = (nbbeats & 0x00ff0000) >> 16;\r
@@ -68,7 +120,7 @@ void MetronomeHaptic::setNbBeats(uint32_t nbbeats)
        \r
        bool written = _comport->WriteData(outBuffer, 5);\r
 
-/*     char INBUFFER[128];\r
+       char INBUFFER[128];\r
        memset(INBUFFER, 0, 128);
        int nbread = _comport->ReadData(INBUFFER, 128);
                        stringstream s;
@@ -96,7 +148,7 @@ int MetronomeHaptic::thread_func(void *obj)
 
 #ifdef WIN32
     struct { int tv_sec, tv_usec; } now;//, start
-       DWORD t = timeGetTime () - BEFOREDELAY;
+       DWORD t = timeGetTime () + BEFOREDELAY;
 /*    start.tv_sec = t / 1000;
     start.tv_usec = (t % 1000) * 1000;*/
 #else
@@ -105,13 +157,10 @@ int MetronomeHaptic::thread_func(void *obj)
 #endif*/
        //float currenttime = 0;
 
-       char outBuffer[5];\r
-       outBuffer[0] = 'S';\r
-       outBuffer[1] = 0;\r
-       outBuffer[2] = 0;\r
-       outBuffer[3] = 0;\r
-       outBuffer[4] = 0;\r
-       bool written = thismetronome->_comport->WriteData(outBuffer, 5);
+       bool written = thismetronome->_comport->WriteData("S", 1);
+       unsigned char outBuffer[6];
+       outBuffer[0] = 'P';
+       unsigned char currentbeat = 0;
 
        while(thismetronome->_activated)
        {
@@ -126,24 +175,33 @@ int MetronomeHaptic::thread_func(void *obj)
 
                while (cBips != bips->end() && currenttime >= BIPTIMESTAMP(*cBips))
                {
-                       char outBuffer[5];\r
-                       outBuffer[0] = 'N';\r
-                       outBuffer[1] = (BIPTIMESTAMP(*cBips) & 0xff000000) >> 24;\r
-                       outBuffer[2] = (BIPTIMESTAMP(*cBips) & 0x00ff0000) >> 16;\r
-                       outBuffer[3] = (BIPTIMESTAMP(*cBips) & 0x0000ff00) >> 8;\r
-                       outBuffer[4] = BIPTIMESTAMP(*cBips) & 0x000000ff;\r
-       \r
-                       bool written = thismetronome->_comport->WriteData(outBuffer, 5);\r
+/*                     char outBuffer[5];\r
+                       outBuffer[0] = 'N';*/\r
+                       outBuffer[1] = currentbeat % 4;\r
+                       outBuffer[2] = (BIPTIMESTAMP(*cBips) & 0xff000000) >> 24;\r
+                       outBuffer[3] = (BIPTIMESTAMP(*cBips) & 0x00ff0000) >> 16;\r
+                       outBuffer[4] = (BIPTIMESTAMP(*cBips) & 0x0000ff00) >> 8;\r
+                       outBuffer[5] = BIPTIMESTAMP(*cBips) & 0x000000ff;\r
+\r
+                       bool written = thismetronome->_comport->WriteData(outBuffer, 6);\r
+/*                     char INBUFFER[128];\r
+                       memset(INBUFFER, 0, 128);
+                       int nbread = thismetronome->_comport->ReadData(INBUFFER, 128);
+                       stringstream s;
+                       s << nbread << " read:\n" << INBUFFER << endl;
+                       OutputDebugString(s.str().c_str());*/\r
+
                        if (logfile)
                                fprintf(logfile, "BIP;%d;%d;%d\n", BIPTICK(*cBips), BIPTIMESTAMP(*cBips), currenttime);
 
+                       currentbeat = (currentbeat + 1) % thismetronome->_nbbeats;
                        cBips++;
                }
 
                // on avance tant que les tempos sont dépassées
                while (cTimesignature != timesignatures->end() && currenttime >= TIMESTAMP(*cTimesignature))
                {
-                       char outBuffer[5];\r
+/*                     char outBuffer[5];\r
                        outBuffer[0] = 'B';\r
                        outBuffer[1] = (TIMESTAMP(*cTimesignature) & 0xff000000) >> 24;\r
                        outBuffer[2] = (TIMESTAMP(*cTimesignature) & 0x00ff0000) >> 16;\r
@@ -151,7 +209,12 @@ int MetronomeHaptic::thread_func(void *obj)
                        outBuffer[4] = TIMESTAMP(*cTimesignature) & 0x000000ff;\r
        \r
                        bool written = thismetronome->_comport->WriteData(outBuffer, 5);\r
-                               
+       */                      
+                       //tempo change
+                       stringstream s;
+                       s << "Time signature change at " << currenttime << " : tick=" << (*cTimesignature).first << " at " << (*cTimesignature).second.getX() << " for " << (*cTimesignature).second.getY() << " beats " << endl;
+                       OutputDebugString(s.str().c_str());
+                       thismetronome->_nbbeats = (*cTimesignature).second.getY();
                        cTimesignature++;
                }
 
index 2c22ee7e030524e7275b7843fcc5e10d5456c6a0..f895c7a08c61bb67f983915a8c9329cea2be6695 100644 (file)
@@ -73,7 +73,7 @@ void Mixer::initMixer()
        }*/
 }
 
-void Mixer::playMusic(const String &filename)
+void Mixer::loadMusic(const String &filename)
 {
        //_debug_(stderr, "playMusic(%s)\n",filename.c_str());
        if (_music)
@@ -95,16 +95,16 @@ void Mixer::playMusic(const String &filename)
 
        if (buffer != "")
        {
-               SDL_mutexP(_mutex);
+//             SDL_mutexP(_mutex);
                _music = Mix_LoadMUS(buffer.c_str());
                if(_music==NULL)
                        fprintf(stderr, "cannot load music %s\n",buffer.c_str());
-               else
+/*             else
                {
                        Mix_PlayMusic(_music, -1);
                        Mix_HookMusicFinished(stopMusic);
-               }
-               SDL_mutexV(_mutex);
+               }*/
+//             SDL_mutexV(_mutex);
        }
        else
                fprintf(stderr, "music file %s not found\n",filename.c_str());
@@ -113,6 +113,15 @@ void Mixer::playMusic(const String &filename)
        //      cout << "music file " << filename << " not found" << endl;
 }
 
+void Mixer::playMusic()
+{
+       if(_music != NULL)
+       {
+               Mix_PlayMusic(_music, -1);
+               Mix_HookMusicFinished(stopMusic);
+       }
+}
+
 void Mixer::stopMusic()
 {
        Mix_HaltMusic();
@@ -133,9 +142,9 @@ bool Mixer::addSound(const String &s, const String &filename)
                snd = _sounds[s];
        }
 
-       SDL_mutexP(_mutex);
+//     SDL_mutexP(_mutex);
        bool res = snd->addSound(filename);
-       SDL_mutexV(_mutex);
+//     SDL_mutexV(_mutex);
 
        return res;
 }
index b0763daf0ccbe7a86ca11b65a5dbfdf4dddb26e1..e585170a89fbcee9bdc1bafbcbd18becbb3b2b32 100644 (file)
@@ -140,8 +140,10 @@ void init()
     throw "Impossible to initialize SDL_GL_MULTISAMPLESAMPLES";
        
 //   int flags = SDL_OPENGL | SDL_OPENGLBLIT | SDL_SWSURFACE | SDL_FULLSCREEN;
-  int flags = SDL_OPENGL | SDL_FULLSCREEN;
+  int flags = SDL_OPENGL;// | SDL_FULLSCREEN;
   SDL_Surface * screen;
+  resolution_x = 1024;
+  resolution_y = 768;
 //  if (!(screen = SDL_SetVideoMode(resolution_x, resolution_y, 0, flags)))
   if (!(screen = SDL_SetVideoMode(resolution_x, resolution_y, 0, flags)))
     throw "Impossible to change the video mode";
@@ -634,8 +636,8 @@ void loop(const Track &tr, const String &songname)
 
        init();
        cout << "Create Metronome" << endl;
-       Metronome *m = new MetronomeAudio(&tr);
-//     Metronome *m = new MetronomeHaptic(&tr);
+//     Metronome *m = new MetronomeAudio(&tr);
+       Metronome *m = new MetronomeHaptic(&tr);
 
        bool quitProgram = false;
 
@@ -649,6 +651,7 @@ void loop(const Track &tr, const String &songname)
 
        cout << "Init paint" << endl;
        initPaint();
+       Mixer::getInstance()->loadMusic(songname + "/tout.ogg");
 
 //must be done before paint and metronomes
 #ifdef WIN32
@@ -662,7 +665,7 @@ void loop(const Track &tr, const String &songname)
        cout << "LET'S ROCK!" << endl;
        //m->setActive(true);
 
-       Mixer::getInstance()->playMusic(songname + "/tout.ogg");
+       Mixer::getInstance()->playMusic();
        m->run();
 /*     Mixer::getInstance()->playSound("guitar");
        if (rhythm)
index 2b6d4d8885e0a8ff9cf7b1a042cac2f44a33cd3e..73f434e484c6a5bf661a9303cc95e462a3e7b146 100644 (file)
@@ -84,7 +84,7 @@ SerialWindows::~SerialWindows()
     }\r
 }\r
 \r
-int SerialWindows::ReadData(char *buffer, unsigned int nbChar)\r
+int SerialWindows::ReadData(void *buffer, unsigned int nbChar)\r
 {\r
     //Number of bytes we'll have read\r
     DWORD bytesRead = 0;\r
@@ -115,12 +115,12 @@ int SerialWindows::ReadData(char *buffer, unsigned int nbChar)
 }\r
 \r
 \r
-bool SerialWindows::WriteData(char *buffer, unsigned int nbChar)\r
+bool SerialWindows::WriteData(void *buffer, unsigned int nbChar)\r
 {\r
     DWORD bytesSend;\r
 \r
     //Try to write the buffer on the Serial port\r
-    if(!WriteFile(_hSerial, (void *)buffer, nbChar, &bytesSend, 0))\r
+    if(!WriteFile(_hSerial, buffer, nbChar, &bytesSend, 0))\r
     {\r
         //In case it don't work get comm error and return false\r
         ClearCommError(_hSerial, &_errors, &_status);\r
index 8b709b86e94bc4f0d65bb058e086445bcd5659bb..c9e2c207c14df5ff336b9bf84346ea34ce206d9c 100644 (file)
@@ -7,6 +7,8 @@
 #include <windows.h>
 #include <iostream>
 #include <sstream>
+#include <algorithm>
+#include <vector>
 using namespace std;
 
 extern Texture* texturesteel, *texturefrett;
@@ -19,7 +21,7 @@ Track::Track()
 {
   for (uint8_t i = 0 ; i < NBDIFFICULTIES ; i++)
   {
-    _currentconfig[i] = 0;
+    _currentconfig[i] = (uint8_t) 0;
     _nbnotes[i] = 0;
     _totallength[i] = 0;
   }
@@ -54,6 +56,39 @@ Track::Track(uint32_t tempo, uint32_t duration)
                _bips.push_back(Pair<uint32_t, uint32_t>(i, i * t / 1000 + 2000));
 }
 
+/**
+       Experimentation track
+       nbbuttons: maximum buttons
+       repetitions: repetitions of all buttons configurations for a given speed
+       nbspeeds: number of speeds
+       speeds: 
+*/
+Track::Track(uint8_t nbbuttons, uint8_t repetitions, uint8_t nbspeeds, uint32_t *speeds)
+{
+       uint32_t tick = 0, timestamp = 2000;
+       addTimesignature(0, 0, 1);
+
+       for (int n = 0 ; n < nbspeeds ; n++)
+       {
+               uint32_t tempo = 60000000 / speeds[n];
+               addTempo(tick, timestamp, tempo);
+               vector<uint8_t> configs;
+
+               for (int i = 1 ; i < (int)pow(2.0, (double)nbbuttons) ; i++)
+                       for (int j = 0 ; j < repetitions ; j++)
+                               configs.push_back(i);
+               random_shuffle(configs.begin(), configs.end());
+
+               for (vector<uint8_t>::iterator it = configs.begin() ; it != configs.end() ; it++)
+               {
+                       for (int d=0 ; d < NBDIFFICULTIES ; d++)
+                               _notes[d][tick] = Config(*it, timestamp, timestamp+100, tick, 1);
+                       tick++;
+                       timestamp += tempo / 1000;
+               }
+       }
+}
+
 Track::~Track()
 {
 }
index f21bc77fbaf85dfd580ec3c3de49c6b08bc82819..f9df849c1406cfe1d7e35f6966965cbdd51ded46 100644 (file)
@@ -48,6 +48,13 @@ int main(int argc, char *argv[])
        struct tm *t  = gmtime(&tim);
 
        cout << "Loading song" << endl;
+       //6 params => toms law experiment
+       // v0 = prog
+       // v1 = condition
+       // v2 = user
+       // v3 = speed
+       // v4 = duration
+       // v5 = distance
        if (argc >= 6)
        {
                Track tr(atoi(argv[3]), atoi(argv[4]));
@@ -61,11 +68,31 @@ int main(int argc, char *argv[])
                //run the game with a click track
                loop(tr, songname);
        }
+       //6 params => speed accuracy experiment
+       // v0 = prog
+       // v1 = condition
+       // v2 = user
+       // v3 = nbbuttons
+       // v4 = nbrepetitions
+       else if (argc >= 5)
+       {
+               uint32_t speeds[] = {40, 80, 120, 160, 200};
+               Track tr(atoi(argv[3]), atoi(argv[4]), 5, speeds);
+               SECONDSIZE = 0.08;
+
+               String logfilename = String(argv[1]) + "-" + String(argv[2]) + "-" + \
+                       String(1900 + t->tm_year) + "-" + String(t->tm_mon) + "-" + String(t->tm_mday) + "-" + \
+                       String(t->tm_hour) + "-" + String(t->tm_min) + "-" + String(t->tm_sec) + "-" + \
+                       String(argv[3]) + "-" + String(argv[4]);
+               logfile = fopen(logfilename.c_str(), "w");
+               //run the game with the experiment track
+               loop(tr, songname);
+       }
        else
        {
                if (argc >= 3)
                {
-                       String logfilename = String(argv[1]) + "-" + String(argv[2]) + "-" + String(1900 + t->tm_year) + "-" + String(t->tm_mon) + "-" + String(t->tm_mday) + "-" + String(t->tm_hour) + "-" + String(t->tm_min) + "-" + String(t->tm_sec) + "-" + String(argv[1]);
+                       String logfilename = String(argv[1]) + "-" + String(argv[2]) + "-" + String(1900 + t->tm_year) + "-" + String(t->tm_mon) + "-" + String(t->tm_mday) + "-" + String(t->tm_hour) + "-" + String(t->tm_min) + "-" + String(t->tm_sec);
                        logfile = fopen(logfilename.c_str(), "w");
                }