rt300@8: // rt300@8: // TrainingMessageOrganiser.mm rt300@8: // riftathon rt300@8: // rt300@8: // Created by Robert Tubb on 17/10/2014. rt300@8: // rt300@8: // rt300@8: rt300@8: #include "TrainingMessageOrganiser.h" rt300@21: rt300@45: void TrainingMessageOrganiser::init( PDSynthWrapper& cs, PDSynthWrapper& ts, bool soundOnlyMode, controlPanelType whichInterfaceAreWeUsing, bool demoMode ){ rt300@21: rt300@21: MessageOrganiser::init(cs,ts); rt300@21: rt300@21: TickListenerFunction callback; rt300@27: callback = boost::bind(&TrainingMessageOrganiser::onNextTickAnim, this, _1); rt300@21: candidateSynth.registerForTicks(callback); rt300@21: rt300@21: numParamsToUse = TOTAL_NUM_PARAMS; rt300@42: rt300@49: sequenceController = new SequenceController(); rt300@49: sequenceController->init(soundOnlyMode,whichInterfaceAreWeUsing, demoMode); rt300@42: rt300@43: setup(whichInterfaceAreWeUsing); rt300@21: } rt300@21: rt300@27: void TrainingMessageOrganiser::setup(controlPanelType whichInterfaceAreWeUsing){ rt300@27: rt300@27: setupDefaultMapping(whichInterfaceAreWeUsing); rt300@27: rt300@39: candidateSynth.setAllParams(expPresetManager.getNeutralPreset()->getValues()); rt300@36: rt300@36: doHand(true); rt300@42: doGuides(false,expPresetManager.getNeutralPreset()); rt300@42: bottomPanel->showAllElements(); rt300@43: rt300@27: } rt300@43: rt300@38: void TrainingMessageOrganiser::setForgotButton(Buttron* butt){ rt300@38: forgotButton = butt; rt300@38: } rt300@27: //---------------------------------------------------------------------------------------- rt300@22: void TrainingMessageOrganiser::showMyPanels(){ rt300@22: presetIconPanel->show(); rt300@22: instructionPanel->show(); rt300@22: bottomPanel->show(); rt300@27: controlPanel->show(); rt300@37: if (panelType == LEAP6DOF){ rt300@37: okToGetMidi = true; // allow midi input to thing rt300@37: }else{ rt300@37: okToGetMidi = false; rt300@37: } rt300@22: } rt300@21: rt300@21: //----------------------------------------------------------------------- rt300@27: void TrainingMessageOrganiser::displayInstructions(string text){ rt300@42: rt300@28: instructionPanel->setText(text); rt300@27: instructionPanel->show(); rt300@42: rt300@21: } rt300@21: rt300@21: //----------------------------------------------------------------------- rt300@21: rt300@21: void TrainingMessageOrganiser::showUserHowTheyDid(){ rt300@21: // colour flash rt300@21: // distance ? rt300@21: // score rt300@21: rt300@21: } rt300@21: rt300@32: rt300@43: rt300@21: //----------------------------------------------------------------------------- rt300@21: rt300@21: void TrainingMessageOrganiser::buttonPressCallback(int mappingID, int value){ rt300@21: if(mappingID == VOLUME_CHANGE_ID){ rt300@21: targetSynth.sendVolume(value); rt300@21: candidateSynth.sendVolume(value); rt300@21: return; rt300@21: } rt300@21: rt300@29: if (mappingID == START_TRAINING_SEQUENCE_ID){ rt300@38: // start next run rt300@38: if (candidateSynth.isMetronomeRunning()){ rt300@38: // skip to next run? rt300@38: eventLogger.logEvent(RUN_SKIPPED); rt300@38: }else{ rt300@49: candidateSynth.setMetroTime(sequenceController->getStartIntervalTime()/4.); rt300@42: candidateSynth.startMetronome(); rt300@47: candidateSynth.playDownbeatBlip(); rt300@42: bottomPanel->hide(); rt300@42: rt300@42: vector details; rt300@42: details.push_back(panelType); rt300@43: // TODO sequence length rt300@42: rt300@42: eventLogger.logEvent(START_NEW_RUN, details); rt300@38: } rt300@21: return; rt300@21: } rt300@21: rt300@37: if(mappingID == TO_MENU_ID){ rt300@37: // tell testapp to start again? rt300@49: // candidateSynth.stopMetronome(); rt300@49: // controlPanel->hide(); rt300@49: // controlPanel->setColor(ofColor::black); rt300@49: // sequenceController->clearAll(); rt300@49: // seqNumPanel->hide(); rt300@49: // eventLogger.logEvent(RUN_SKIPPED); rt300@49: // eventLogger.saveSessionToFile(); rt300@49: reset(); rt300@38: } rt300@37: rt300@38: if(mappingID == FORGOT_SEQ_ID){ rt300@38: // rt300@38: eventLogger.logEvent(FORGOT_SEQ); rt300@38: cout << "FORGOT" << endl; rt300@37: } rt300@43: if(mappingID == SKIP_RUN_ID){ rt300@49: sequenceController->skipRun(); rt300@49: int r = sequenceController->getCurrentRunNumber(); rt300@43: stringstream s; rt300@49: s << ">> " << r+1; rt300@43: skipButton->setLabel(s.str()); rt300@43: rt300@43: rt300@43: } rt300@37: rt300@21: } rt300@21: //----------------------------------------------------------------------------- rt300@27: rt300@27: //----------------------------------------------------------------------- rt300@27: void TrainingMessageOrganiser::onNextTick(int tickNumber){ rt300@27: static int showingCountdown = false; rt300@42: rt300@27: downCounter = 4 - tickNumber % 4; rt300@27: rt300@27: if (showingCountdown){ rt300@27: middlePanel->setText(ofToString(downCounter)); rt300@27: } rt300@27: rt300@27: // only first beat in bar is active one rt300@27: if ( tickNumber % 4 != 0){ rt300@27: rt300@27: return; rt300@27: } rt300@27: rt300@27: } rt300@32: void TrainingMessageOrganiser::lastOfRun(int which){ rt300@27: candidateSynth.stopMetronome(); rt300@32: stringstream s; rt300@32: rt300@49: s << "FINISHED RUN " << which << " OF " << sequenceController->getTotNumRuns() << endl; rt300@50: rt300@50: if ((which % 3) == 0){ rt300@50: s << "sequence will be 1 sound long"; rt300@50: } rt300@50: if ((which % 3) == 1){ rt300@50: s << "sequence will be 2 sounds long"; rt300@50: } rt300@50: if ((which % 3) == 2){ rt300@50: s << "sequence will be 3 sounds long"; rt300@50: } rt300@27: controlPanel->hide(); rt300@36: controlPanel->setColor(ofColor::black); rt300@36: middlePanel->setText(s.str()); rt300@27: middlePanel->show(); rt300@32: //playCandidateButton->setLabel("NEXT"); rt300@44: s.str(""); rt300@50: s << "skp" << which+1; rt300@43: skipButton->setLabel(s.str()); rt300@43: rt300@29: bottomPanel->show(); rt300@32: seqNumPanel->hide(); rt300@42: forgotButton->hide(); rt300@49: instructionPanel->setText(""); rt300@33: eventLogger.logEvent(FINISHED_RUN); rt300@34: eventLogger.saveSessionToFile(); rt300@43: // TODO keep track of how far we are into experiment rt300@27: } rt300@27: void TrainingMessageOrganiser::lastOfAll(){ rt300@27: candidateSynth.stopMetronome(); rt300@29: cout << "FINISHED BLOCK" << endl; rt300@27: controlPanel->hide(); rt300@36: controlPanel->setColor(ofColor::black); rt300@43: middlePanel->setText("CONGRATULATIONS.\n FINISHED BLOCK!"); rt300@27: middlePanel->show(); rt300@50: //bottomPanel->showOnlyElementNamed("MENU"); rt300@29: bottomPanel->show(); rt300@35: seqNumPanel->hide(); rt300@42: forgotButton->hide(); rt300@50: eventLogger.logEvent(FINISHED_RUN); rt300@34: eventLogger.saveSessionToFile(); rt300@27: } rt300@32: rt300@42: void TrainingMessageOrganiser::logNewStep(AnimStep newStep, vector targetVals){ rt300@32: rt300@32: vector details; rt300@32: details.push_back(int(newStep.type)); rt300@32: details.push_back(newStep.whichInSequence); rt300@32: details.push_back(newStep.showsGuides); rt300@32: details.push_back(newStep.showsIcons); rt300@32: details.push_back(newStep.presetIndex); rt300@32: details.push_back(newStep.tempo); rt300@42: details.insert(details.end(),targetVals.begin(), targetVals.end()); rt300@32: eventLogger.logEvent(NEW_STEP, details); rt300@32: rt300@32: } rt300@32: rt300@27: //----------------------------------------------------------------------------- rt300@27: void TrainingMessageOrganiser::onNextTickAnim(int tickNumber){ rt300@31: static AnimStep oldStep; rt300@35: static vector lastPosition = zeros(TOTAL_NUM_PARAMS); rt300@27: rt300@35: //cout << "TICK " << tickNumber << endl; rt300@27: rt300@50: // HALF METRO rt300@50: bool halfMetro = false; rt300@50: rt300@50: if ( halfMetro){ rt300@50: downCounter = 2 - tickNumber % 2; rt300@50: rt300@50: if ( tickNumber % 2 != 0) { rt300@50: if (tickNumber % 2 == 1){ rt300@50: targetSynth.sendAllParams(); rt300@50: } rt300@50: return; rt300@50: }; rt300@50: }else{ rt300@50: downCounter = 4 - tickNumber % 4; rt300@50: rt300@50: updateCountdown(downCounter); rt300@50: // only first beat in bar is active one (at the moment) rt300@50: // send next target values 1 step before them play rt300@50: if ( tickNumber % 4 != 0) { rt300@50: if (tickNumber % 4 == 3){ rt300@50: targetSynth.sendAllParams(); rt300@50: } rt300@50: return; rt300@50: }; rt300@50: } rt300@27: rt300@27: rt300@31: Preset* previousTargetPreset; rt300@31: vector curCandidateSettings = candidateSynth.getAllParamValues(); rt300@31: if (oldStep.showsResultsAtEnd){ rt300@42: // this if should be in getpreset rt300@31: if(oldStep.presetIndex == -1){ rt300@31: previousTargetPreset = expPresetManager.getNeutralPreset(); rt300@31: cout << "SHOULDNT SCORE NEUTRAL??" << endl; rt300@31: }else{ rt300@31: rt300@31: previousTargetPreset = expPresetManager.getPresetAtIndex(oldStep.presetIndex); rt300@31: } rt300@33: rt300@33: eventLogger.logEvent(FINISH_POS, curCandidateSettings); rt300@31: TrainingTestResult result = doResults(oldStep, rt300@31: previousTargetPreset, rt300@31: lastPosition, rt300@31: curCandidateSettings); rt300@31: rt300@31: flashResult(result); rt300@31: } rt300@31: rt300@49: AnimStep newStep = sequenceController->getNextStep(); // ADVANCES COUNTS rt300@27: rt300@42: rt300@32: rt300@27: if(newStep.isLastOfAll){ rt300@49: oldStep = newStep; rt300@27: lastOfAll(); rt300@27: return; rt300@27: } rt300@27: if(newStep.isLastOfRun){ rt300@49: oldStep = newStep; rt300@32: lastOfRun(newStep.runNumber); rt300@27: return; rt300@27: } rt300@50: if(halfMetro){ rt300@50: candidateSynth.setMetroTime(newStep.getTimeBetweenTicks()*2); rt300@50: }else{ rt300@50: candidateSynth.setMetroTime(newStep.getTimeBetweenTicks()); rt300@50: } rt300@35: Preset * currentTargetPreset; rt300@35: if(newStep.presetIndex == -1){ rt300@35: currentTargetPreset = expPresetManager.getNeutralPreset(); rt300@37: rt300@35: }else{ rt300@35: rt300@35: currentTargetPreset = expPresetManager.getPresetAtIndex(newStep.presetIndex); rt300@35: if (currentTargetPreset == NULL){ rt300@50: displayInstructions("No stored preset!\n please restert and choose EXP"); rt300@43: rt300@43: bottomPanel->show(); rt300@50: //bottomPanel->showOnlyElementNamed("MENU"); rt300@35: candidateSynth.stopMetronome(); rt300@35: return; rt300@35: } rt300@35: } rt300@27: rt300@27: switch (newStep.type){ rt300@27: case AnimStep::PREVIEW_NEUTRAL_COUNT : rt300@35: previewNeutralCount(newStep,currentTargetPreset); rt300@27: break; rt300@27: case AnimStep::PREVIEW_MOVE : rt300@35: previewMove(newStep,currentTargetPreset); rt300@27: break; rt300@35: case AnimStep::PREVIEW_LAST : rt300@35: previewLast( newStep,currentTargetPreset); rt300@27: break; rt300@27: case AnimStep::MATCHING_NEUTRAL_COUNT : rt300@35: //matchingNeutralCount( newStep,currentTargetPreset); rt300@27: break; rt300@27: case AnimStep::MATCHING_MOVE : rt300@35: matchingMove( newStep,currentTargetPreset); rt300@27: break; rt300@35: case AnimStep::MATCHING_LAST : rt300@35: matchingLast( newStep,currentTargetPreset); rt300@27: break; rt300@31: case AnimStep::GUIDED_MOVE : rt300@35: //guidedMove( newStep); rt300@31: break; rt300@31: rt300@31: case AnimStep::GUIDED_HIT : rt300@35: //guidedHit( newStep); rt300@31: break; rt300@31: default: rt300@31: break; rt300@27: } rt300@42: logNewStep(newStep, currentTargetPreset->getValues()); rt300@31: oldStep = newStep; rt300@31: lastPosition = curCandidateSettings; rt300@31: rt300@27: } rt300@27: //----------------------------------------------------------------------------- rt300@27: void TrainingMessageOrganiser::updateCountdown(int n){ rt300@27: rt300@27: } rt300@27: //----------------------------------------------------------------------------- rt300@35: void TrainingMessageOrganiser::previewNeutralCount(AnimStep newStep, Preset * currentTargetPreset){ rt300@32: okToGetMidi = false; rt300@37: candidateSynth.playDownbeatBlip(); rt300@28: middlePanel->hide(); rt300@42: rt300@27: // your 'hand' is hidden rt300@27: controlPanel->showValueIndicators(false); rt300@27: rt300@27: rt300@27: // guide is set to neutral values rt300@27: currentTargetPreset = expPresetManager.getNeutralPreset(); rt300@27: vector newTargetValues = currentTargetPreset->getValues(); rt300@35: controlPanel->setValues(newTargetValues); rt300@27: presetIconPanel->setTextAndImage(currentTargetPreset->name, currentTargetPreset->getImage(), false); rt300@27: presetIconPanel->show(); rt300@42: rt300@27: controlPanel->setAndShowHint(newTargetValues, currentTargetPreset->getImage()); rt300@36: doHand(false); rt300@36: controlPanel->show(); rt300@27: rt300@27: targetSynth.setAllParams(newTargetValues); rt300@36: //candidateSynth.setAllParams(newTargetValues); rt300@27: rt300@50: displayInstructions("Prepare for next \n sequence preview"); rt300@32: seqNumPanel->hide(); rt300@49: rt300@36: controlPanel->setColor(ofColor::black); rt300@27: } rt300@27: //----------------------------------------------------------------------------- rt300@35: void TrainingMessageOrganiser::previewMove(AnimStep newStep, Preset * currentTargetPreset){ rt300@42: rt300@35: targetSynth.trigger(); // PLAYS LAST TARGET rt300@42: rt300@42: rt300@27: vector newTargetValues = currentTargetPreset->getValues(); rt300@42: rt300@31: targetSynth.setAllParamsWithoutSend(newTargetValues); rt300@27: rt300@35: doGuides(newStep.showsGuides, currentTargetPreset); rt300@42: rt300@35: doHand(false, newStep.showsGuides, newStep.getTimeBetweenTicks()*4, newTargetValues); rt300@32: rt300@35: doIcons(newStep.showsIcons, currentTargetPreset); rt300@42: rt300@42: rt300@27: controlPanel->show(); rt300@42: rt300@35: displayInstructions("PREVIEW"); rt300@48: if(newStep.showsGuides){ rt300@48: showSeqNum(newStep.whichInSequence); rt300@48: }else{ rt300@48: showSeqNum(-1); rt300@48: } rt300@36: rt300@36: controlPanel->setColor(ofColor::black); rt300@39: bottomPanel->hide(); rt300@38: forgotButton->hide(); rt300@38: forgotButton->turnOff(); rt300@27: } rt300@35: rt300@35: rt300@27: //----------------------------------------------------------------------------- rt300@32: // lest setep of preview seq - plays moves back to neutral pos? rt300@35: void TrainingMessageOrganiser::previewLast(AnimStep newStep, Preset * currentTargetPreset){ rt300@35: targetSynth.trigger(); rt300@42: rt300@35: // wrong? rt300@35: targetSynth.setAllParamsWithoutSend(currentTargetPreset->getValues()); rt300@27: rt300@35: // your hand shows, we dont bother animating back to neutral!? rt300@35: doHand(true); rt300@42: rt300@35: doIcons(newStep.showsIcons,currentTargetPreset); rt300@27: rt300@35: doGuides(newStep.showsGuides, currentTargetPreset); rt300@42: rt300@35: showSeqNum(newStep.whichInSequence); rt300@43: displayInstructions("PREVIEW FINISHED"); rt300@39: // set candidate and sliders to neutral rt300@39: candidateSynth.setAllParams(expPresetManager.getNeutralPreset()->getValues()); rt300@36: controlPanel->setColor(ofColor::darkMagenta); rt300@27: } rt300@31: rt300@31: //----------------------------------------------------------------------------- rt300@35: void TrainingMessageOrganiser::matchingMove(AnimStep newStep, Preset * currentTargetPreset){ rt300@42: rt300@31: rt300@28: middlePanel->hide(); rt300@42: rt300@27: vector newTargetValues = currentTargetPreset->getValues(); rt300@33: eventLogger.logEvent(NEW_TARGET, newTargetValues); rt300@35: targetSynth.setAllParamsWithoutSend(newTargetValues); rt300@42: rt300@31: // if showing guides show the hint hand rt300@35: doGuides(newStep.showsGuides, currentTargetPreset); rt300@27: rt300@35: doIcons(newStep.showsIcons, currentTargetPreset); rt300@27: rt300@35: doHand(true); rt300@35: rt300@42: if (newStep.showsGuides){ rt300@42: displayInstructions("MATCH THE GUIDES"); rt300@43: // trigger "guide sound"? rt300@43: triggerCandidateSound(); rt300@42: }else{ rt300@42: displayInstructions("MATCH WITHOUT GUIDES"); rt300@42: } rt300@35: showSeqNum(newStep.whichInSequence); rt300@31: // trigger where we're at at the moment rt300@29: triggerCandidateSound(); rt300@42: rt300@49: rt300@41: if (!newStep.showsGuides || !newStep.showsIcons){ rt300@41: controlPanel->setColor(ofColor::red); rt300@41: // set sliders to default texture rt300@41: controlPanel->setIndicatorTexture(NULL); rt300@39: forgotButton->show(); rt300@41: }else{ rt300@42: rt300@41: controlPanel->setColor(ofColor::darkMagenta); rt300@42: rt300@42: rt300@36: } rt300@27: } rt300@27: //----------------------------------------------------------------------------- rt300@35: void TrainingMessageOrganiser::matchingLast(AnimStep newStep, Preset * currentTargetPreset){ rt300@35: // why is this different from match it? rt300@35: rt300@27: vector newTargetValues = currentTargetPreset->getValues(); rt300@33: eventLogger.logEvent(NEW_TARGET, newTargetValues); rt300@35: targetSynth.setAllParamsWithoutSend(newTargetValues); rt300@27: rt300@35: doGuides(newStep.showsGuides, currentTargetPreset); rt300@27: rt300@35: doIcons(newStep.showsIcons, currentTargetPreset); rt300@32: rt300@35: doHand(true); rt300@35: rt300@37: //displayInstructions("MATCHING FINISHED"); rt300@35: showSeqNum(newStep.whichInSequence); rt300@42: rt300@33: triggerCandidateSound(); rt300@49: rt300@41: if (!newStep.showsGuides || !newStep.showsIcons){ rt300@41: controlPanel->setColor(ofColor::red); rt300@41: // set sliders to default texture rt300@41: controlPanel->setIndicatorTexture(NULL); rt300@41: forgotButton->show(); rt300@36: }else{ rt300@41: rt300@41: controlPanel->setColor(ofColor::darkMagenta); rt300@41: rt300@41: rt300@36: } rt300@31: } rt300@31: //----------------------------------------------------------------------------- rt300@31: rt300@35: TrainingTestResult TrainingMessageOrganiser::doResults(AnimStep step, rt300@31: Preset * targetPreset, rt300@31: vector startingPosition, rt300@31: vector currentPosition){ rt300@34: // targetParams, startPosition, answer, timeAllowed rt300@28: TrainingTestResult result = rt300@34: rt300@34: trainingScoreManager.getScoreForAnswer(targetPreset->getValues(), rt300@31: startingPosition, rt300@34: currentPosition, rt300@36: step.getTimeAllowed(), rt300@36: step.difficulty, rt300@36: step.whichInSequence, rt300@36: step.presetIndex, rt300@36: step.tempoLevel, rt300@43: step.totalLengthOfSeq); rt300@28: rt300@49: sequenceController->saveResultForCurrentStep(result); rt300@31: instructionPanel->setColor(result.colorBand); rt300@42: rt300@42: rt300@31: displayInstructions(result.displayText); rt300@28: rt300@32: showScoreNum(trainingScoreManager.getScore()); rt300@32: rt300@31: return result; rt300@27: } rt300@27: rt300@31: void TrainingMessageOrganiser::flashResult(TrainingTestResult r){ rt300@31: rt300@31: // stick a colored number over target position rt300@39: controlPanel->flashResultLight(r.colorBand, r.timeAllowed*ofGetFrameRate()/6000.); rt300@42: rt300@31: rt300@31: } rt300@35: rt300@35: rt300@35: //------------------------------------------------------------------------------------ rt300@35: void TrainingMessageOrganiser::doIcons(bool showIcons, Preset * currentTargetPreset){ rt300@35: rt300@35: if (showIcons){ rt300@35: presetIconPanel->setTextAndImage(currentTargetPreset->name, currentTargetPreset->getImage(), false); rt300@35: presetIconPanel->show(); rt300@35: }else{ rt300@35: presetIconPanel->hide(); rt300@35: } rt300@35: } rt300@35: //------------------------------------------------------------------------------------ rt300@35: void TrainingMessageOrganiser::doGuides(bool showGuides, Preset * currentTargetPreset){ rt300@35: rt300@35: // show icon and guides rt300@35: if (showGuides){ // always show neutral one rt300@35: rt300@35: // show where we're going rt300@35: controlPanel->setAndShowHint(currentTargetPreset->getValues(), currentTargetPreset->getImage()); rt300@38: if (panelType == LEAP6DOF) distanceSlider->show(); rt300@35: rt300@35: }else{ rt300@35: controlPanel->showHint(false); rt300@38: distanceSlider->hide(); rt300@35: } rt300@41: // special case - always show guide for neutral position rt300@39: if(currentTargetPreset->name == "Neutral"){ rt300@39: controlPanel->setAndShowHint(currentTargetPreset->getValues(), currentTargetPreset->getImage()); rt300@39: } rt300@35: rt300@35: } rt300@35: //----------------------------------------------------------------------------- rt300@35: void TrainingMessageOrganiser::doHand(bool showControllableHand, bool showAnimatedHand, float animTime, vector newTargetValues) rt300@35: { rt300@35: // show how to get there rt300@35: if (showAnimatedHand){ rt300@44: //if (panelType == LEAP6DOF){ rt300@35: controlPanel->animateToNewValues(newTargetValues, animTime); rt300@35: controlPanel->showValueIndicators(true); // for animation rt300@35: controlPanel->setActive(false); rt300@44: //} rt300@35: rt300@35: }else if(showControllableHand){ rt300@35: controlPanel->showValueIndicators(true); // for animation rt300@35: controlPanel->setActive(true); // allow user control rt300@37: if (panelType == LEAP6DOF){ rt300@37: okToGetMidi = true; // allow midi input to thing rt300@37: }else{ rt300@37: okToGetMidi = false; rt300@38: setSlidersToCandidate(); // cos hand won't be controlling them rt300@37: } rt300@35: rt300@35: }else{ rt300@35: controlPanel->showValueIndicators(false); // hand/ slider bars invisible rt300@35: controlPanel->setActive(false); // cant control it rt300@35: } rt300@35: rt300@35: } rt300@48: //----------------------------------------------------------------------------- rt300@48: rt300@43: void TrainingMessageOrganiser::forgotByMidi(){ rt300@43: forgotButton->turnOn(); rt300@43: buttonPressCallback(FORGOT_SEQ_ID, 1); rt300@48: } rt300@48: //----------------------------------------------------------------------------- rt300@48: rt300@48: void TrainingMessageOrganiser::reset(){ rt300@50: // DONT CALL THIS! rt300@48: // tell testapp to start again? rt300@48: candidateSynth.stopMetronome(); rt300@48: controlPanel->hide(); rt300@48: controlPanel->setColor(ofColor::black); rt300@49: sequenceController->clearAll(); rt300@49: trainingScoreManager.reset(); rt300@48: seqNumPanel->hide(); rt300@50: //eventLogger.saveSessionToFile(); //? rt300@48: rt300@48: } rt300@48: //-----------------------------------------------------------------------------