changeset 43:4ad0d218f890

can skip runs if it crashed etc.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Mon, 15 Dec 2014 12:51:09 +0000
parents 2bd658b44c2d
children d810aa9ca03a
files ExpMessageOrganiser.mm MessageOrganiser.h MessageOrganiser.mm SequenceController.h SequenceController.mm TrainingMessageOrganiser.h TrainingMessageOrganiser.mm TrainingScoreManager.h UI code/Buttron.h UI code/IconPanel.mm UI code/UIElement.mm UI code/UIProperties.h eventLogger.h globalVariables.h testApp.mm
diffstat 15 files changed, 267 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- a/ExpMessageOrganiser.mm	Mon Dec 08 18:29:10 2014 +0000
+++ b/ExpMessageOrganiser.mm	Mon Dec 15 12:51:09 2014 +0000
@@ -102,7 +102,7 @@
             instructionPanel->show();
             bottomPanel->show();
             bottomPanel->showOnlyElementNamed("MENU");
-
+            okToGetMidi = false;
             controlPanel->hide();
             
         }else{
--- a/MessageOrganiser.h	Mon Dec 08 18:29:10 2014 +0000
+++ b/MessageOrganiser.h	Mon Dec 15 12:51:09 2014 +0000
@@ -67,10 +67,12 @@
     void setControlPanel(SliderPanel* p);
     void setBottomPanel(ButtonPanel * ntb);
     void setIconPanel(IconPanel * ip);
+    void setSkipButton(Buttron* b);
     void setInstructionPanel(TextPanel * ip);
     void setSeqNumPanel(TextPanel * snp);
     void setScoreNumPanel(TextPanel * snp);
     void setDistanceSlider(ButtronSlider * s);
+    void setMiddlePanel(TextPanel* tp);
     //-----------------------------------------------------------------------------
     void hideMyPanels();
     void showMyPanels();
@@ -88,6 +90,7 @@
     TextPanel* instructionPanel;
     TextPanel * seqNumPanel;
     TextPanel * scoreNumPanel;
+    TextPanel* middlePanel;
     map<int,UIElement*> currentMapping; // could get more sophisticated if not 1-1 ?
     
     vector<int> getMappingIDsFromSynths();
@@ -119,5 +122,7 @@
     bool okToGetMidi;
     controlPanelType panelType;
     ButtronSlider * distanceSlider;
+    Buttron* skipButton;
+    
 };
 
--- a/MessageOrganiser.mm	Mon Dec 08 18:29:10 2014 +0000
+++ b/MessageOrganiser.mm	Mon Dec 15 12:51:09 2014 +0000
@@ -60,10 +60,16 @@
     bottomPanel = ntb;
 };
 //----------------------------------------------------------------------------------
-
+void MessageOrganiser::setSkipButton(Buttron* b){
+    skipButton = b;
+}
 void MessageOrganiser::setIconPanel(IconPanel * ip){
     presetIconPanel = ip;
 }
+//----------------------------------------------------------------------------------------
+void MessageOrganiser::setMiddlePanel(TextPanel* tp){
+    middlePanel = tp;
+}
 //----------------------------------------------------------------------------------
 void MessageOrganiser::setInstructionPanel(TextPanel * ip){
     instructionPanel = ip;
@@ -97,6 +103,8 @@
     instructionPanel->hide();
     bottomPanel->hide();
     controlPanel->hide();
+    middlePanel->hide();
+    okToGetMidi = false;
 }
 //----------------------------------------------------------------------------------
 void MessageOrganiser::showMyPanels(){
@@ -298,6 +306,7 @@
     candidateSynth.setAllParams(rands);
     
 }
+
 //----------------------------------------------------------------------------------
 
 
--- a/SequenceController.h	Mon Dec 08 18:29:10 2014 +0000
+++ b/SequenceController.h	Mon Dec 15 12:51:09 2014 +0000
@@ -16,9 +16,9 @@
 
 #define MIN_TARGETS_IN_SEQUENCE 1
 #define NUM_REPETITIONS_AT_LEVEL 2
-#define MAX_TARGETS_IN_SEQUENCE 3
-#define MIN_TEMPO   70
-#define MAX_TEMPO   500
+#define MAX_TARGETS_IN_SEQUENCE 4
+#define MIN_TEMPO   90
+#define MAX_TEMPO   520
 #define TEMPO_RANDOM_AMOUNT
 #define MAX_TIME 2800
 #define MIN_TIME 200
@@ -55,7 +55,7 @@
     }
 
     void setTempoFromTime(){
-        tempo = 60.0 / (4* timeAllowedMs*1000.0);
+        tempo = 4 * 1000. * 60.0 / (timeAllowedMs);
     }
     void setTimeFromTempo(){
         timeAllowedMs = 4*1000* (60.0/tempo);
@@ -78,7 +78,7 @@
     bool showsGuides; // depends on 'level'
     bool showsIcons;
     bool showsResultsAtEnd;
-    
+    int totalLengthOfSeq;
     vector<int> thisSequence; // so that we can show the whole sequence at the top?
     
     TrainingTestResult result; // only applies to steps that were scored.
@@ -132,19 +132,22 @@
 class SequenceController{
 public:
     SequenceController();
-    void init(bool asoundOnlyMode);
+    void init(bool asoundOnlyMode, controlPanelType whichInterfaceAreWeUsing);
     AnimStep getNextStep();
     void setToStart();
     void stepForward();
-    float getStartTickTime();
+    float getStartIntervalTime();
     void saveResultForCurrentStep(TrainingTestResult result);
     TrainingTestResult getResultForPreviousStep();
     int getTotNumRuns(){return totNumRuns;};
+    int getCurrentRunNumber(){return currentRunNumber;};
+    void skipRun();
 private:
     void generateSteps();
-    void generateCountIn(int countInLength);
-    void generateRun(int run, int numInSequence);
-    void generateARun(int run, int numInSequence); // use this
+    void generateTestSequence();
+    void generateCountIn(int countInLength, int runNumber);
+    void generateRun(int run, int numInSequence);// use this now
+    void generateARun(int run, int numInSequence);
     void generateAnEasyRun(int run, int numInSequence = 1);
     void generateASoundOnlyRun(int run, int numInSequence);
     vector<int> randomSequence(int numInSequence);
@@ -159,7 +162,10 @@
     float tempoInc;
     int timeInc;
     bool soundOnlyMode;
+    controlPanelType panelType;
     int totNumRuns;
+    vector<int> timeIntervalsHard;
+    int currentRunNumber;
 };
 
 #endif /* defined(__riftathon__SequenceGenerator__) */
--- a/SequenceController.mm	Mon Dec 08 18:29:10 2014 +0000
+++ b/SequenceController.mm	Mon Dec 15 12:51:09 2014 +0000
@@ -11,7 +11,7 @@
     type = PREVIEW_NEUTRAL_COUNT;
     presetIndex = -1;
     seqNumber = -1;
-    runNumber = -1;
+    runNumber = 0;
     whichInSequence = -1;
     
     tempo = MIN_TEMPO;
@@ -25,6 +25,7 @@
     showsResultsAtEnd = false;
     difficulty = 0;
     setTimeFromTempo();
+    totalLengthOfSeq = 0;
 }
 
 void AnimStep::saveResult(TrainingTestResult aresult){
@@ -157,15 +158,48 @@
 //=================================================================
 
 SequenceController::SequenceController(){
-
+    int tih[] = {
+        2637,
+        2337,
+        2123,
+        1791,
+        1538,
+        1355,
+        1206,
+        1090,
+        991,
+        912,
+        842,
+        784,
+        731,
+        687,
+        646,
+        612,
+        551,
+        502
+    };
+    for(int i = 0; i < 25; i++){
+        timeIntervalsHard.push_back(tih[i]);
+    }
+    
+    currentRunNumber = 0; // actually goes from 1 0 is pre-start
+    
 };
 //-------------------------------------------------------------------
-void SequenceController::init(bool asoundOnlyMode){
+void SequenceController::init(bool asoundOnlyMode, controlPanelType whichInterfaceAreWeUsing){
     soundOnlyMode = asoundOnlyMode;
+    panelType = whichInterfaceAreWeUsing;
     tempoInc = float(MAX_TEMPO - MIN_TEMPO) / float(NUM_TEMPO_STEPS);
     timeInc = (MAX_TIME - MIN_TIME) / NUM_TEMPO_STEPS;
-    generateSteps();
+    
+    if (true){
+        generateSteps();
+    }else{
+        generateTestSequence();
+    }
+    
     setToStart();
+    
 };
 //-------------------------------------------------------------------
 AnimStep SequenceController::getNextStep(){
@@ -183,37 +217,55 @@
 //-------------------------------------------------------------------
 void SequenceController::setToStart(){
     currentStep = steps.begin();
+    currentRunNumber = (*currentStep).runNumber;
+}
+//-------------------------------------------------------------------
+void SequenceController::skipRun(){
+    // loop thru steps until next run reached
+    bool nextRunReached = false;
+    
+    while (!nextRunReached){
+        currentStep++;
+        if ((*currentStep).runNumber != currentRunNumber && (*currentStep).runNumber != 0){
+            nextRunReached = true;
+            currentRunNumber = (*currentStep).runNumber;
+        }
+    }
 }
 //-------------------------------------------------------------------
 void SequenceController::stepForward(){
     currentStep++;
 };
 //-------------------------------------------------------------------
-float SequenceController::getStartTickTime(){
-    return 1000. * (60.0/MIN_TEMPO);
+float SequenceController::getStartIntervalTime(){
+    float t =  timeIntervalsHard[0];
+    if (panelType == ALL_SLIDERS){
+        t = 1.5*t;
+    }
+    return t;
 }
 //-------------------------------------------------------------------
 void SequenceController::generateSteps(){
     srand (time(NULL));
     
-    int run = 0;
+    int run = 1;
     
     
     
     for(int numInSequence = MIN_TARGETS_IN_SEQUENCE; numInSequence <= MAX_TARGETS_IN_SEQUENCE; numInSequence++){
         
         for(int rep = 0; rep < NUM_REPETITIONS_AT_LEVEL; rep++){
-        
-        generateCountIn(1);
-        
-        if (soundOnlyMode){
-            generateASoundOnlyRun(run, numInSequence);
-        }else {
-            generateRun(run, numInSequence);
-        }
-        steps.back().isLastOfRun = true;
-        run++;
-        cout << "-generate run finished-" << endl;
+            
+            generateCountIn(1,run);
+            
+            if (soundOnlyMode){
+                generateASoundOnlyRun(run, numInSequence);
+            }else {
+                generateRun(run, numInSequence);
+            }
+            steps.back().isLastOfRun = true;
+            run++;
+            cout << "-generate run finished-" << endl;
         }
     }
     totNumRuns = run;
@@ -221,14 +273,56 @@
 };
 
 //-------------------------------------------------------------------
+void SequenceController::generateTestSequence(){
+    // just make something simple to check sanity
+    generateCountIn(2,1);
+    
+    vector<int> seq = nonRandomSequence(2);
+    
+    // first we have a preparation count in
+    AnimStep nextStep;
+    nextStep.presetIndex = -1; // minus one means "blank"
+    nextStep.runNumber = 1;
+    nextStep.seqNumber = 1;
+    nextStep.whichInSequence = 0;
+    //nextStep.tempo = curTempo;
+    nextStep.tempoLevel = 0;
+    //        nextStep.setTimeFromTempo();
+    nextStep.timeAllowedMs = timeIntervalsHard[0];
+    if (panelType == ALL_SLIDERS){
+        nextStep.timeAllowedMs = 1.5*nextStep.timeAllowedMs;
+    }
+    nextStep.setTempoFromTime();
+    nextStep.showsGuides = true;
+    nextStep.difficulty = 0;
+    nextStep.type = AnimStep::PREVIEW_NEUTRAL_COUNT;
+    nextStep.showsResultsAtEnd = false;
+    
 
+    steps.push_back(nextStep);
+    
+    makePreview(seq, 0, nextStep);
 
-void SequenceController::generateCountIn(int countInLength){
+    makeGuidedSequence(seq, 0, nextStep);
+
+    makeMatchingSequence(seq, 0, nextStep);
+    
+    totNumRuns = 1;
+    steps.back().isLastOfAll = true;
+    
+}
+//-------------------------------------------------------------------
+
+
+void SequenceController::generateCountIn(int countInLength, int runNumber){
     AnimStep countStep;
     for (int i = 0; i < countInLength; i++){
         countStep.whichInSequence = countInLength - i + 1;
         countStep.type = AnimStep::PREVIEW_NEUTRAL_COUNT;
         countStep.showsResultsAtEnd = false;
+        countStep.runNumber = runNumber;
+        countStep.timeAllowedMs = getStartIntervalTime();
+        countStep.setTempoFromTime();
         steps.push_back(countStep);
         
     }
@@ -251,7 +345,7 @@
 
 vector<int> SequenceController::nonRandomSequence(int numInSequence){
     vector<int> stepPresetIndices;
-    // get some random ints
+    // 1,2,3,4 you know the score
     for(int n=0; n < numInSequence; n++){
         int nextPreset = n;
         stepPresetIndices.push_back(nextPreset);
@@ -275,9 +369,14 @@
         nextStep.runNumber = run;
         nextStep.seqNumber = seqNo;
         nextStep.whichInSequence = 0;
-        nextStep.tempo = curTempo;
+        //nextStep.tempo = curTempo;
         nextStep.tempoLevel = tempoLevel;
-        nextStep.setTimeFromTempo();
+//        nextStep.setTimeFromTempo();
+        nextStep.timeAllowedMs = timeIntervalsHard[tempoLevel];
+        if (panelType == ALL_SLIDERS){
+            nextStep.timeAllowedMs = 1.5*nextStep.timeAllowedMs;
+        }
+        nextStep.setTempoFromTime();
         nextStep.showsGuides = true;
         nextStep.difficulty = 0;
         nextStep.type = AnimStep::PREVIEW_NEUTRAL_COUNT;
@@ -294,7 +393,7 @@
         // generate a sequence of random preset indices
         vector<int> stepPresetIndices = randomSequence(numInSequence);
         nextStep.thisSequence = stepPresetIndices;
-        
+        nextStep.totalLengthOfSeq = numInSequence;
         makePreview(stepPresetIndices, run, nextStep);
         
         // make GUIDED sequence (1 and 2)
@@ -307,7 +406,7 @@
         
         steps.back().isLastOfSeq = true;
         if(numInSequence == 1){
-            curTempo += tempoInc*0.8; // easier!!!??? will mess up time points
+            curTempo += tempoInc; // easier!!!??? will mess up time points
         }else{
             curTempo += tempoInc;
         }
@@ -315,6 +414,7 @@
         cout << endl;
         
     }
+
     // ANIM nextStep.setAsBlankCounter();
     nextStep.type = AnimStep::MATCHING_NEUTRAL_COUNT;
     steps.push_back(nextStep);
@@ -360,7 +460,6 @@
         nextStep.presetIndex = *si;
         nextStep.runNumber = run;
         nextStep.whichInSequence = n;
-        nextStep.setTimeFromTempo();
         nextStep.showsGuides = true;
         nextStep.showsIcons = true;
         nextStep.showsResultsAtEnd = true;
@@ -395,7 +494,6 @@
         nextStep.presetIndex = *si;
         nextStep.runNumber = run;
         nextStep.whichInSequence = n;
-        nextStep.setTimeFromTempo();
         nextStep.showsGuides = false;
         nextStep.showsIcons = false;
         nextStep.showsResultsAtEnd = true;
@@ -425,14 +523,17 @@
     float curTempo = MIN_TEMPO;
     int seqNo = 0;
     AnimStep nextStep;
+    nextStep.totalLengthOfSeq = numInSequence;
+    
     for(int tempoLevel = 0; tempoLevel < NUM_TEMPO_STEPS; tempoLevel++){
         // first we have a preparation count in
         nextStep.presetIndex = -1; // minus one means "blank"
         nextStep.runNumber = run;
         nextStep.seqNumber = seqNo;
         nextStep.whichInSequence = 0;
+        
         nextStep.difficulty = 0;
-        nextStep.tempo = curTempo;
+        nextStep.tempo = curTempo; // TODO
         nextStep.showsGuides = true; // guide shown for neutral point
         nextStep.type = AnimStep::PREVIEW_NEUTRAL_COUNT;
         nextStep.showsResultsAtEnd = false;
@@ -443,6 +544,7 @@
         nextStep.thisSequence = stepPresetIndices;
         
         makePreview(stepPresetIndices, run, nextStep);
+        makePreview(stepPresetIndices, run, nextStep);
         
         // make matching sequence without icon seq help
         makeMatchingSequence(stepPresetIndices, run, nextStep);
@@ -486,7 +588,7 @@
         // generate a sequence of random preset indices
         vector<int> stepPresetIndices = randomSequence(numInSequence);
         nextStep.thisSequence = stepPresetIndices;
-
+        
         // make preview sequence
         int n = 1;
         for(auto si = stepPresetIndices.begin(); si < stepPresetIndices.end(); si++){
@@ -496,7 +598,7 @@
             nextStep.runNumber = run;
             nextStep.seqNumber = seqNo;
             nextStep.whichInSequence = n;
-
+            
             nextStep.showsGuides = true;
             nextStep.showsIcons = true;
             nextStep.showsResultsAtEnd = false;
@@ -526,13 +628,13 @@
             nextStep.presetIndex = *si;
             nextStep.seqNumber = seqNo;
             nextStep.whichInSequence = n;
-
+            
             nextStep.showsGuides = true;
             nextStep.showsIcons = true;
             nextStep.showsResultsAtEnd = true;
             nextStep.type = AnimStep::MATCHING_MOVE;
             steps.push_back(nextStep);
-
+            
             if (SPACER_BARS){
                 nextStep.type = AnimStep::MATCHING_LAST;
                 steps.push_back(nextStep);
@@ -554,7 +656,7 @@
             nextStep.difficulty = 2;
             nextStep.presetIndex = *si;
             nextStep.whichInSequence = n;
-
+            
             nextStep.showsGuides = false;
             nextStep.showsIcons = true;
             nextStep.type = AnimStep::MATCHING_MOVE;
@@ -564,10 +666,10 @@
             if (SPACER_BARS){
                 nextStep.type = AnimStep::MATCHING_LAST;
                 steps.push_back(nextStep);
-            
+                
             }
             n++;
-
+            
         }
         
         // move back to neutral
@@ -628,13 +730,13 @@
 //-----------------------------------------------------------------------
 TrainingTestResult SequenceController::getResultForPreviousStep(){
     if (currentStep == steps.begin()){
-
+        
         cout << "ERROR - " << endl;
-
+        
     }
     return (*currentStep--).result;
     
-
+    
 }
 //-----------------------------------------------------------------------
 
--- a/TrainingMessageOrganiser.h	Mon Dec 08 18:29:10 2014 +0000
+++ b/TrainingMessageOrganiser.h	Mon Dec 15 12:51:09 2014 +0000
@@ -25,8 +25,8 @@
 class TrainingMessageOrganiser : public MessageOrganiser {
 public:
     int numParamsToUse;
-    void init( PDSynthWrapper& cs, PDSynthWrapper& ts, bool soundOnlyMode);
-    void setMiddlePanel(TextPanel* tp);
+    void init( PDSynthWrapper& cs, PDSynthWrapper& ts, bool soundOnlyMode,controlPanelType whichInterfaceAreWeUsing);
+    
     void setup(controlPanelType whichInterfaceAreWeUsing);
     vector<int> getMappingIDsFromSynths();
     void displayInstructions(string text);
@@ -35,6 +35,7 @@
     
     void showMyPanels();
     void setForgotButton(Buttron* butt);
+    void forgotByMidi();
     //void midiFromLeap(int ctl_num, int ctl_val);
     //-----------------------------------------------------------------------
 protected:
@@ -79,7 +80,7 @@
     
     vector<int> oldTargetValues;
     //-----------------------------------------------------------------------------
-    TextPanel* middlePanel;
+    
     SequenceController sequenceController;
     TrainingScoreManager trainingScoreManager;
     Buttron* forgotButton;
--- a/TrainingMessageOrganiser.mm	Mon Dec 08 18:29:10 2014 +0000
+++ b/TrainingMessageOrganiser.mm	Mon Dec 15 12:51:09 2014 +0000
@@ -8,7 +8,7 @@
 
 #include "TrainingMessageOrganiser.h"
 
-void TrainingMessageOrganiser::init( PDSynthWrapper& cs, PDSynthWrapper& ts, bool soundOnlyMode){
+void TrainingMessageOrganiser::init( PDSynthWrapper& cs, PDSynthWrapper& ts, bool soundOnlyMode, controlPanelType whichInterfaceAreWeUsing){
     
     MessageOrganiser::init(cs,ts);
     
@@ -18,9 +18,9 @@
     
     numParamsToUse = TOTAL_NUM_PARAMS;
     
-    sequenceController.init(soundOnlyMode);
+    sequenceController.init(soundOnlyMode,whichInterfaceAreWeUsing);
     
-    
+    setup(whichInterfaceAreWeUsing);
 }
 
 void TrainingMessageOrganiser::setup(controlPanelType whichInterfaceAreWeUsing){
@@ -32,11 +32,9 @@
     doHand(true);
     doGuides(false,expPresetManager.getNeutralPreset());
     bottomPanel->showAllElements();
+
 }
-//----------------------------------------------------------------------------------------
-void TrainingMessageOrganiser::setMiddlePanel(TextPanel* tp){
-    middlePanel = tp;
-}
+
 void TrainingMessageOrganiser::setForgotButton(Buttron* butt){
     forgotButton = butt;
 }
@@ -46,7 +44,6 @@
     instructionPanel->show();
     bottomPanel->show();
     controlPanel->show();
-    middlePanel->show();
     if (panelType == LEAP6DOF){
         okToGetMidi = true; // allow midi input to thing
     }else{
@@ -72,6 +69,7 @@
 }
 
 
+
 //-----------------------------------------------------------------------------
 
 void TrainingMessageOrganiser::buttonPressCallback(int mappingID, int value){
@@ -87,12 +85,13 @@
             // skip to next run?
             eventLogger.logEvent(RUN_SKIPPED);
         }else{
-            candidateSynth.setMetroTime(sequenceController.getStartTickTime());
+            candidateSynth.setMetroTime(sequenceController.getStartIntervalTime()/4.);
             candidateSynth.startMetronome();
             bottomPanel->hide();
             
             vector<int> details;
             details.push_back(panelType);
+            // TODO sequence length
             
             eventLogger.logEvent(START_NEW_RUN, details);
         }
@@ -114,6 +113,15 @@
         eventLogger.logEvent(FORGOT_SEQ);
         cout << "FORGOT" << endl;
     }
+    if(mappingID == SKIP_RUN_ID){
+        sequenceController.skipRun();
+        int r = sequenceController.getCurrentRunNumber();
+        stringstream s;
+        s << "SKIP RUN " << r;
+        skipButton->setLabel(s.str());
+        
+    
+    }
     
 }
 //-----------------------------------------------------------------------------
@@ -139,24 +147,29 @@
     candidateSynth.stopMetronome();
     stringstream s;
     
-    s << "FINISHED RUN " << which+1 << " OF " << sequenceController.getTotNumRuns() << endl;
+    s << "FINISHED RUN " << which << " OF " << sequenceController.getTotNumRuns() << endl;
     controlPanel->hide();
     controlPanel->setColor(ofColor::black);
     middlePanel->setText(s.str());
     middlePanel->show();
     //playCandidateButton->setLabel("NEXT");
+
+    s << "SKIP RUN " << which+1;
+    skipButton->setLabel(s.str());
+    
     bottomPanel->show();
     seqNumPanel->hide();
     forgotButton->hide();
     eventLogger.logEvent(FINISHED_RUN);
     eventLogger.saveSessionToFile();
+    // TODO keep track of how far we are into experiment
 }
 void TrainingMessageOrganiser::lastOfAll(){
     candidateSynth.stopMetronome();
     cout << "FINISHED BLOCK" << endl;
     controlPanel->hide();
     controlPanel->setColor(ofColor::black);
-    middlePanel->setText("CONGRATULATIONS. FINISHED BLOCK!");
+    middlePanel->setText("CONGRATULATIONS.\n FINISHED BLOCK!");
     middlePanel->show();
     bottomPanel->showOnlyElementNamed("MENU");
     bottomPanel->show();
@@ -242,6 +255,8 @@
         currentTargetPreset =  expPresetManager.getPresetAtIndex(newStep.presetIndex);
         if (currentTargetPreset == NULL){
             displayInstructions("No stored preset!\n please go back to menu and choose EXP");
+            
+            bottomPanel->show();
             bottomPanel->showOnlyElementNamed("MENU");
             candidateSynth.stopMetronome();
             return;
@@ -361,7 +376,7 @@
     doGuides(newStep.showsGuides, currentTargetPreset);
     
     showSeqNum(newStep.whichInSequence);
-    displayInstructions("Preview FINISHED");
+    displayInstructions("PREVIEW FINISHED");
     // set candidate and sliders to neutral
     candidateSynth.setAllParams(expPresetManager.getNeutralPreset()->getValues());
     controlPanel->setColor(ofColor::darkMagenta);
@@ -386,6 +401,8 @@
     
     if (newStep.showsGuides){
         displayInstructions("MATCH THE GUIDES");
+        // trigger "guide sound"?
+        triggerCandidateSound();
     }else{
         displayInstructions("MATCH WITHOUT GUIDES");
     }
@@ -455,7 +472,7 @@
                                            step.whichInSequence,
                                            step.presetIndex,
                                            step.tempoLevel,
-                                           step.runNumber);
+                                           step.totalLengthOfSeq);
     
     sequenceController.saveResultForCurrentStep(result);
     instructionPanel->setColor(result.colorBand);
@@ -512,9 +529,11 @@
 {
     // show how to get there
     if (showAnimatedHand){
+        if (panelType == LEAP6DOF){
         controlPanel->animateToNewValues(newTargetValues, animTime);
         controlPanel->showValueIndicators(true); // for animation
         controlPanel->setActive(false);
+        }
         
     }else if(showControllableHand){
         controlPanel->showValueIndicators(true); // for animation
@@ -532,3 +551,7 @@
     }
     
 }
+void TrainingMessageOrganiser::forgotByMidi(){
+    forgotButton->turnOn();
+    buttonPressCallback(FORGOT_SEQ_ID, 1);
+}
\ No newline at end of file
--- a/TrainingScoreManager.h	Mon Dec 08 18:29:10 2014 +0000
+++ b/TrainingScoreManager.h	Mon Dec 15 12:51:09 2014 +0000
@@ -58,13 +58,9 @@
         }else if (dist < TARGET_SCORE_CC_BAND*6*dimComp){ // 30
             
             band = 5;
-
-            
         }else if (dist < TARGET_SCORE_CC_BAND*9*dimComp){ // 45
             
-            band = 6;
-
-            
+            band = 6;   
         }else{
             
             band = 7;
@@ -136,7 +132,7 @@
                                          int whichInSequence,
                                          int presetIndex,
                                          int tempoLevel,
-                                         int runNumber) {
+                                         int seqLength) {
         TrainingTestResult result;
         stringstream msg;
         int score = 0;
@@ -162,7 +158,7 @@
         result.realDistanceToTarget = dist;
         result.targetBandHit = band; // eg bullseye = 0 edge = 7
         result.timeAllowed = timeAllowed;
-        result.score = int(round(TP*10.0));
+        result.score = int(round(TP));
         result.displayText = msg.str();
         result.difficultyLevel = difficulty;
         result.colorBand = getColorForBand(band);
@@ -181,7 +177,7 @@
         details.push_back(initDist*1000);
         details.push_back(presetIndex);
         details.push_back(tempoLevel);
-        details.push_back(runNumber);
+        details.push_back(seqLength);
         eventLogger.logEvent(TRAINING_RESULT, details);
         details.clear();
         details.insert(details.begin(), targetParams.begin(), targetParams.end());
--- a/UI code/Buttron.h	Mon Dec 08 18:29:10 2014 +0000
+++ b/UI code/Buttron.h	Mon Dec 15 12:51:09 2014 +0000
@@ -73,6 +73,9 @@
     void turnOff(){
         on = false;
     }
+    void turnOn(){
+        on = true;
+    }
     virtual bool handleMyTouch(int x, int y, touchType ttype, int touchID);
 
 protected:
--- a/UI code/IconPanel.mm	Mon Dec 08 18:29:10 2014 +0000
+++ b/UI code/IconPanel.mm	Mon Dec 15 12:51:09 2014 +0000
@@ -79,7 +79,7 @@
 void IconPanel::drawTexture(){
     float z = 10;
     ofSetColor(255,255,255);
-    textureImage->draw(x+30,y+30,z,width-20,height-30);
+    textureImage->draw(x+30,y+5,z,width-20,height-30);
     ofSetColor(foregroundHi);
 }
 //------------------------------------------------------------------
@@ -97,7 +97,7 @@
         fg = fgInactive;
     }
     ofSetColor(fg);
-    verdana16.drawString(labelName, x + 40, y + 8);
+    verdana16.drawString(labelName, x + 40, y + height - 10);
     
 }
 //------------------------------------------------------------------
--- a/UI code/UIElement.mm	Mon Dec 08 18:29:10 2014 +0000
+++ b/UI code/UIElement.mm	Mon Dec 15 12:51:09 2014 +0000
@@ -87,7 +87,11 @@
 //----------------------------------------------------------------------
 // called first from all subclasses
 bool UIElement::isMyTouch(int tx, int ty, touchType ttype, int touchID){
-    if(hidden || inactive) return false;
+    if(hidden || inactive){
+        // what if get made hidden or inactive when you're touching it ?
+        myTouchIDs.clear(); // just release them all
+        return false;
+    }
 
     if(ttype == TOUCH_DOWN){
         if (touchIsInMyArea(tx, ty)){
--- a/UI code/UIProperties.h	Mon Dec 08 18:29:10 2014 +0000
+++ b/UI code/UIProperties.h	Mon Dec 15 12:51:09 2014 +0000
@@ -63,7 +63,7 @@
         spacerSize = 40;
         XYsize = sliderPanelHeight - spacerSize*2;
         
-        sliderWidth = XYsize/4;
+        sliderWidth = XYsize/3;
         sliderHeight = XYsize;
         sliderMinVal = 0.   ;
         sliderMaxVal = 127.;
--- a/eventLogger.h	Mon Dec 08 18:29:10 2014 +0000
+++ b/eventLogger.h	Mon Dec 15 12:51:09 2014 +0000
@@ -73,17 +73,17 @@
                 START_THE_PERFORMANCE_TESTS,     // 26 starting perf
     
     // new stuff for TRaining stage
-                START_NEW_RUN,
-                TRAINING_RESULT,
-                NEW_STEP,
-                NEW_TARGET,
-                NEW_START_POS,
-                FINISH_POS,
-                FINISHED_RUN,
-                CANDIDATE_PARAM_ADJUSTED_ALL,
-                TARGET_AND_MATCH,
-                FORGOT_SEQ,
-    RUN_SKIPPED
+                START_NEW_RUN,              // 27
+                TRAINING_RESULT,            // 28
+                NEW_STEP,                   // 29
+                NEW_TARGET,                 // 30
+                NEW_START_POS,              //31
+                FINISH_POS,                 //32
+                FINISHED_RUN,               //33
+                CANDIDATE_PARAM_ADJUSTED_ALL,   //34
+                TARGET_AND_MATCH,           //35
+                FORGOT_SEQ,             //36
+    RUN_SKIPPED                         //37
     
 };
 
--- a/globalVariables.h	Mon Dec 08 18:29:10 2014 +0000
+++ b/globalVariables.h	Mon Dec 15 12:51:09 2014 +0000
@@ -27,6 +27,7 @@
 #define START_TRAINING_SEQUENCE_ID 99189938
 #define SAVE_PRESET_HIT     99245748
 #define TO_MENU_ID          99545741
+#define SKIP_RUN_ID         99765346
 #define FORGOT_SEQ_ID       99123123
 #define RECALL_PRESET_HIT   99298750
 #define ALTERNATION_SPEED 180 // ms that target / candidate sounds play
--- a/testApp.mm	Mon Dec 08 18:29:10 2014 +0000
+++ b/testApp.mm	Mon Dec 15 12:51:09 2014 +0000
@@ -146,7 +146,7 @@
 
 
     Buttron * forgotButton = new Buttron(props->buttonWidth*1.4,680, *props);
-    forgotButton->setLabel("FORGOT SEQ");
+    forgotButton->setLabel("FORGOT!");
     trainingMessageOrganiser.mapButtonToAction(forgotButton, FORGOT_SEQ_ID);
     trainingMessageOrganiser.setForgotButton(forgotButton);
     UIElements.push_back(forgotButton);
@@ -165,6 +165,13 @@
     //trainingMessageOrganiser.mapButtonToAction(menuButton, TO_MENU_ID);
     bottomButtonPanel->addButton(menuButton);
     
+    Buttron * skipButton = new Buttron(props->buttonWidth*1.4,680, *props);
+    skipButton->setLabel("SKIP RUN 1");
+    trainingMessageOrganiser.mapButtonToAction(skipButton, SKIP_RUN_ID);
+    trainingMessageOrganiser.setSkipButton(skipButton);
+    //trainingMessageOrganiser.mapButtonToAction(menuButton, TO_MENU_ID);
+    bottomButtonPanel->addButton(skipButton);
+    
     bottomButtonPanel->hide();
     
     ButtronSlider* distanceSlider = new ButtronSlider(ofGetWidth()-80, 200, 60, ofGetHeight()-400, FILL, *props);
@@ -183,11 +190,7 @@
     trainingMessageOrganiser.setInstructionPanel(instructionPanel);
     instructionPanel->hide();
     
-    TextPanel * middlePanel = new TextPanel("Middle panel", 400, 400, 400,400,(*props));
-    middlePanel->setFontSize(LARGEFONT);
-    UIElements.push_back(middlePanel);
-    trainingMessageOrganiser.setMiddlePanel(middlePanel);
-    middlePanel->hide();
+
     
     
 }
@@ -317,6 +320,14 @@
     UIElements.push_back(scoreNumPanel);
     scoreNumPanel->show();
     
+    TextPanel * middlePanel = new TextPanel("Middle panel", 400, 400, 400,400,(*props));
+    middlePanel->setFontSize(LARGEFONT);
+    UIElements.push_back(middlePanel);
+    expMessageOrganiser.setMiddlePanel(middlePanel);
+    trainingMessageOrganiser.setMiddlePanel(middlePanel);
+    searchMessageOrganiser.setMiddlePanel(middlePanel);
+    middlePanel->hide();
+    
 //    Leap6DBox * box = new Leap6DBox(400 , 210 , (*props).XYsize*0.75,(*props).XYsize*0.75,150,50, *props);
 //    searchMessageOrganiser.setBox(box);
 //    trainingMessageOrganiser.setBox(box);
@@ -501,6 +512,7 @@
     trainingMessageOrganiser.hideMyPanels();
     searchMessageOrganiser.hideMyPanels();
     [introViewController show:(__bridge id)this];
+    eventLogger.logEvent(RUN_SKIPPED);
 }
 //-------------------------------
 void testApp::interfaceSelected(int interfaceSelection){
@@ -553,9 +565,8 @@
 void testApp::startTheTrainingTests(){
     eventLogger.logEvent(START_THE_TRAINING_TESTS);
     expMessageOrganiser.hideMyPanels();
-    trainingMessageOrganiser.init(targetSynth,candidateSynth, false);
-    
-    trainingMessageOrganiser.setup(whichInterfaceAreWeUsing);
+    trainingMessageOrganiser.init(targetSynth,candidateSynth, false,whichInterfaceAreWeUsing);
+
     trainingMessageOrganiser.showMyPanels();
     currentStage = TRAINING;
 }
@@ -563,9 +574,8 @@
 void testApp::startThePerformanceTests(){
     eventLogger.logEvent(START_THE_PERFORMANCE_TESTS);
     
-    trainingMessageOrganiser.init(targetSynth,candidateSynth, true);
-    
-    trainingMessageOrganiser.setup(whichInterfaceAreWeUsing);
+    trainingMessageOrganiser.init(targetSynth,candidateSynth, true,whichInterfaceAreWeUsing);
+
     trainingMessageOrganiser.showMyPanels();
     currentStage = TRAINING;
 }
@@ -825,6 +835,13 @@
             trainingMessageOrganiser.midiFromLeap(ctl_num, ctl_val);
         
     }
+    
+    if(msg.channel == midiChannel && msg.status == MIDI_NOTE_ON){
+        // if(msg.value;
+        // turn on forget button
+        if (currentStage == TRAINING)
+            trainingMessageOrganiser.forgotByMidi();
+    }
  
 }