Mercurial > hg > tweakathon2ios
view TrainingMessageOrganiser.mm @ 44:d810aa9ca03a
times. cosmetic stuff
author | Robert Tubb <rt300@eecs.qmul.ac.uk> |
---|---|
date | Mon, 15 Dec 2014 17:33:41 +0000 |
parents | 4ad0d218f890 |
children | 80112c9349c4 |
line wrap: on
line source
// // TrainingMessageOrganiser.mm // riftathon // // Created by Robert Tubb on 17/10/2014. // // #include "TrainingMessageOrganiser.h" void TrainingMessageOrganiser::init( PDSynthWrapper& cs, PDSynthWrapper& ts, bool soundOnlyMode, controlPanelType whichInterfaceAreWeUsing){ MessageOrganiser::init(cs,ts); TickListenerFunction callback; callback = boost::bind(&TrainingMessageOrganiser::onNextTickAnim, this, _1); candidateSynth.registerForTicks(callback); numParamsToUse = TOTAL_NUM_PARAMS; sequenceController.init(soundOnlyMode,whichInterfaceAreWeUsing); setup(whichInterfaceAreWeUsing); } void TrainingMessageOrganiser::setup(controlPanelType whichInterfaceAreWeUsing){ setupDefaultMapping(whichInterfaceAreWeUsing); candidateSynth.setAllParams(expPresetManager.getNeutralPreset()->getValues()); doHand(true); doGuides(false,expPresetManager.getNeutralPreset()); bottomPanel->showAllElements(); } void TrainingMessageOrganiser::setForgotButton(Buttron* butt){ forgotButton = butt; } //---------------------------------------------------------------------------------------- void TrainingMessageOrganiser::showMyPanels(){ presetIconPanel->show(); instructionPanel->show(); bottomPanel->show(); controlPanel->show(); if (panelType == LEAP6DOF){ okToGetMidi = true; // allow midi input to thing }else{ okToGetMidi = false; } } //----------------------------------------------------------------------- void TrainingMessageOrganiser::displayInstructions(string text){ instructionPanel->setText(text); instructionPanel->show(); } //----------------------------------------------------------------------- void TrainingMessageOrganiser::showUserHowTheyDid(){ // colour flash // distance ? // score } //----------------------------------------------------------------------------- void TrainingMessageOrganiser::buttonPressCallback(int mappingID, int value){ if(mappingID == VOLUME_CHANGE_ID){ targetSynth.sendVolume(value); candidateSynth.sendVolume(value); return; } if (mappingID == START_TRAINING_SEQUENCE_ID){ // start next run if (candidateSynth.isMetronomeRunning()){ // skip to next run? eventLogger.logEvent(RUN_SKIPPED); }else{ 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); } return; } if(mappingID == TO_MENU_ID){ // tell testapp to start again? candidateSynth.stopMetronome(); controlPanel->hide(); controlPanel->setColor(ofColor::black); seqNumPanel->hide(); eventLogger.logEvent(RUN_SKIPPED); eventLogger.saveSessionToFile(); } if(mappingID == FORGOT_SEQ_ID){ // eventLogger.logEvent(FORGOT_SEQ); cout << "FORGOT" << endl; } if(mappingID == SKIP_RUN_ID){ sequenceController.skipRun(); int r = sequenceController.getCurrentRunNumber(); stringstream s; s << "GOTO RUN " << r+1; skipButton->setLabel(s.str()); } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------- void TrainingMessageOrganiser::onNextTick(int tickNumber){ static int showingCountdown = false; downCounter = 4 - tickNumber % 4; if (showingCountdown){ middlePanel->setText(ofToString(downCounter)); } // only first beat in bar is active one if ( tickNumber % 4 != 0){ return; } } void TrainingMessageOrganiser::lastOfRun(int which){ candidateSynth.stopMetronome(); stringstream s; s << "FINISHED RUN " << which << " OF " << sequenceController.getTotNumRuns() << endl; controlPanel->hide(); controlPanel->setColor(ofColor::black); middlePanel->setText(s.str()); middlePanel->show(); //playCandidateButton->setLabel("NEXT"); s.str(""); s << "GOTO 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.\n FINISHED BLOCK!"); middlePanel->show(); bottomPanel->showOnlyElementNamed("MENU"); bottomPanel->show(); seqNumPanel->hide(); forgotButton->hide(); eventLogger.saveSessionToFile(); } void TrainingMessageOrganiser::logNewStep(AnimStep newStep, vector<int> targetVals){ vector<int> details; details.push_back(int(newStep.type)); details.push_back(newStep.whichInSequence); details.push_back(newStep.showsGuides); details.push_back(newStep.showsIcons); details.push_back(newStep.presetIndex); details.push_back(newStep.tempo); details.insert(details.end(),targetVals.begin(), targetVals.end()); eventLogger.logEvent(NEW_STEP, details); } //----------------------------------------------------------------------------- void TrainingMessageOrganiser::onNextTickAnim(int tickNumber){ static AnimStep oldStep; static vector<int> lastPosition = zeros<int>(TOTAL_NUM_PARAMS); //cout << "TICK " << tickNumber << endl; downCounter = 4 - tickNumber % 4; updateCountdown(downCounter); // only first beat in bar is active one (at the moment) // send next target values 1 step before them play if ( tickNumber % 4 != 0) { if (tickNumber % 4 == 3){ targetSynth.sendAllParams(); } return; }; Preset* previousTargetPreset; vector<int> curCandidateSettings = candidateSynth.getAllParamValues(); if (oldStep.showsResultsAtEnd){ // this if should be in getpreset if(oldStep.presetIndex == -1){ previousTargetPreset = expPresetManager.getNeutralPreset(); cout << "SHOULDNT SCORE NEUTRAL??" << endl; }else{ previousTargetPreset = expPresetManager.getPresetAtIndex(oldStep.presetIndex); } eventLogger.logEvent(FINISH_POS, curCandidateSettings); TrainingTestResult result = doResults(oldStep, previousTargetPreset, lastPosition, curCandidateSettings); flashResult(result); } AnimStep newStep = sequenceController.getNextStep(); // ADVANCES COUNTS if(newStep.isLastOfAll){ lastOfAll(); return; } if(newStep.isLastOfRun){ lastOfRun(newStep.runNumber); return; } candidateSynth.setMetroTime(newStep.getTimeBetweenTicks()); Preset * currentTargetPreset; if(newStep.presetIndex == -1){ currentTargetPreset = expPresetManager.getNeutralPreset(); }else{ 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; } } switch (newStep.type){ case AnimStep::PREVIEW_NEUTRAL_COUNT : previewNeutralCount(newStep,currentTargetPreset); break; case AnimStep::PREVIEW_MOVE : previewMove(newStep,currentTargetPreset); break; case AnimStep::PREVIEW_LAST : previewLast( newStep,currentTargetPreset); break; case AnimStep::MATCHING_NEUTRAL_COUNT : //matchingNeutralCount( newStep,currentTargetPreset); break; case AnimStep::MATCHING_MOVE : matchingMove( newStep,currentTargetPreset); break; case AnimStep::MATCHING_LAST : matchingLast( newStep,currentTargetPreset); break; case AnimStep::GUIDED_MOVE : //guidedMove( newStep); break; case AnimStep::GUIDED_HIT : //guidedHit( newStep); break; default: break; } logNewStep(newStep, currentTargetPreset->getValues()); oldStep = newStep; lastPosition = curCandidateSettings; } //----------------------------------------------------------------------------- void TrainingMessageOrganiser::updateCountdown(int n){ } //----------------------------------------------------------------------------- void TrainingMessageOrganiser::previewNeutralCount(AnimStep newStep, Preset * currentTargetPreset){ okToGetMidi = false; candidateSynth.playDownbeatBlip(); middlePanel->hide(); // your 'hand' is hidden controlPanel->showValueIndicators(false); // guide is set to neutral values currentTargetPreset = expPresetManager.getNeutralPreset(); vector<int> newTargetValues = currentTargetPreset->getValues(); controlPanel->setValues(newTargetValues); presetIconPanel->setTextAndImage(currentTargetPreset->name, currentTargetPreset->getImage(), false); presetIconPanel->show(); controlPanel->setAndShowHint(newTargetValues, currentTargetPreset->getImage()); doHand(false); controlPanel->show(); targetSynth.setAllParams(newTargetValues); //candidateSynth.setAllParams(newTargetValues); displayInstructions("Get ready for preview"); seqNumPanel->hide(); oldTargetValues = newTargetValues; controlPanel->setColor(ofColor::black); } //----------------------------------------------------------------------------- void TrainingMessageOrganiser::previewMove(AnimStep newStep, Preset * currentTargetPreset){ targetSynth.trigger(); // PLAYS LAST TARGET vector<int> newTargetValues = currentTargetPreset->getValues(); targetSynth.setAllParamsWithoutSend(newTargetValues); doGuides(newStep.showsGuides, currentTargetPreset); doHand(false, newStep.showsGuides, newStep.getTimeBetweenTicks()*4, newTargetValues); doIcons(newStep.showsIcons, currentTargetPreset); controlPanel->show(); displayInstructions("PREVIEW"); showSeqNum(newStep.whichInSequence); oldTargetValues = newTargetValues; controlPanel->setColor(ofColor::black); bottomPanel->hide(); forgotButton->hide(); forgotButton->turnOff(); } //----------------------------------------------------------------------------- // lest setep of preview seq - plays moves back to neutral pos? void TrainingMessageOrganiser::previewLast(AnimStep newStep, Preset * currentTargetPreset){ targetSynth.trigger(); // wrong? targetSynth.setAllParamsWithoutSend(currentTargetPreset->getValues()); // your hand shows, we dont bother animating back to neutral!? doHand(true); doIcons(newStep.showsIcons,currentTargetPreset); doGuides(newStep.showsGuides, currentTargetPreset); showSeqNum(newStep.whichInSequence); displayInstructions("PREVIEW FINISHED"); // set candidate and sliders to neutral candidateSynth.setAllParams(expPresetManager.getNeutralPreset()->getValues()); controlPanel->setColor(ofColor::darkMagenta); } //----------------------------------------------------------------------------- void TrainingMessageOrganiser::matchingMove(AnimStep newStep, Preset * currentTargetPreset){ middlePanel->hide(); vector<int> newTargetValues = currentTargetPreset->getValues(); eventLogger.logEvent(NEW_TARGET, newTargetValues); targetSynth.setAllParamsWithoutSend(newTargetValues); // if showing guides show the hint hand doGuides(newStep.showsGuides, currentTargetPreset); doIcons(newStep.showsIcons, currentTargetPreset); doHand(true); if (newStep.showsGuides){ displayInstructions("MATCH THE GUIDES"); // trigger "guide sound"? triggerCandidateSound(); }else{ displayInstructions("MATCH WITHOUT GUIDES"); } showSeqNum(newStep.whichInSequence); // trigger where we're at at the moment triggerCandidateSound(); oldTargetValues = newTargetValues; if (!newStep.showsGuides || !newStep.showsIcons){ controlPanel->setColor(ofColor::red); // set sliders to default texture controlPanel->setIndicatorTexture(NULL); forgotButton->show(); }else{ controlPanel->setColor(ofColor::darkMagenta); } } //----------------------------------------------------------------------------- void TrainingMessageOrganiser::matchingLast(AnimStep newStep, Preset * currentTargetPreset){ // why is this different from match it? vector<int> newTargetValues = currentTargetPreset->getValues(); eventLogger.logEvent(NEW_TARGET, newTargetValues); targetSynth.setAllParamsWithoutSend(newTargetValues); doGuides(newStep.showsGuides, currentTargetPreset); doIcons(newStep.showsIcons, currentTargetPreset); doHand(true); //displayInstructions("MATCHING FINISHED"); showSeqNum(newStep.whichInSequence); triggerCandidateSound(); oldTargetValues = newTargetValues; if (!newStep.showsGuides || !newStep.showsIcons){ controlPanel->setColor(ofColor::red); // set sliders to default texture controlPanel->setIndicatorTexture(NULL); forgotButton->show(); }else{ controlPanel->setColor(ofColor::darkMagenta); } } //----------------------------------------------------------------------------- TrainingTestResult TrainingMessageOrganiser::doResults(AnimStep step, Preset * targetPreset, vector<int> startingPosition, vector<int> currentPosition){ // targetParams, startPosition, answer, timeAllowed TrainingTestResult result = trainingScoreManager.getScoreForAnswer(targetPreset->getValues(), startingPosition, currentPosition, step.getTimeAllowed(), step.difficulty, step.whichInSequence, step.presetIndex, step.tempoLevel, step.totalLengthOfSeq); sequenceController.saveResultForCurrentStep(result); instructionPanel->setColor(result.colorBand); displayInstructions(result.displayText); showScoreNum(trainingScoreManager.getScore()); return result; } void TrainingMessageOrganiser::flashResult(TrainingTestResult r){ // stick a colored number over target position controlPanel->flashResultLight(r.colorBand, r.timeAllowed*ofGetFrameRate()/6000.); } //------------------------------------------------------------------------------------ void TrainingMessageOrganiser::doIcons(bool showIcons, Preset * currentTargetPreset){ if (showIcons){ presetIconPanel->setTextAndImage(currentTargetPreset->name, currentTargetPreset->getImage(), false); presetIconPanel->show(); }else{ presetIconPanel->hide(); } } //------------------------------------------------------------------------------------ void TrainingMessageOrganiser::doGuides(bool showGuides, Preset * currentTargetPreset){ // show icon and guides if (showGuides){ // always show neutral one // show where we're going controlPanel->setAndShowHint(currentTargetPreset->getValues(), currentTargetPreset->getImage()); if (panelType == LEAP6DOF) distanceSlider->show(); }else{ controlPanel->showHint(false); distanceSlider->hide(); } // special case - always show guide for neutral position if(currentTargetPreset->name == "Neutral"){ controlPanel->setAndShowHint(currentTargetPreset->getValues(), currentTargetPreset->getImage()); } } //----------------------------------------------------------------------------- void TrainingMessageOrganiser::doHand(bool showControllableHand, bool showAnimatedHand, float animTime, vector<int> newTargetValues) { // 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 controlPanel->setActive(true); // allow user control if (panelType == LEAP6DOF){ okToGetMidi = true; // allow midi input to thing }else{ okToGetMidi = false; setSlidersToCandidate(); // cos hand won't be controlling them } }else{ controlPanel->showValueIndicators(false); // hand/ slider bars invisible controlPanel->setActive(false); // cant control it } } void TrainingMessageOrganiser::forgotByMidi(){ forgotButton->turnOn(); buttonPressCallback(FORGOT_SEQ_ID, 1); }