rt300@8: // rt300@8: // TrainingMessageOrganiser.h rt300@8: // riftathon rt300@8: // rt300@8: // Created by Robert Tubb on 17/10/2014. rt300@8: // rt300@8: // rt300@8: rt300@8: #ifndef __riftathon__TrainingMessageOrganiser__ rt300@8: #define __riftathon__TrainingMessageOrganiser__ rt300@8: rt300@8: #include rt300@9: #include "MessageOrganiser.h" rt300@10: #include "SequenceController.h" rt300@11: #include "globalVariables.h" rt300@12: #include "IconPanel.h" rt300@12: rt300@10: extern ExplorePresetManager expPresetManager; rt300@10: rt300@9: class TrainingMessageOrganiser : public MessageOrganiser { rt300@9: public: rt300@14: int numParamsToUse; rt300@9: void init( PDSynthWrapper& cs, PDSynthWrapper& ts){ rt300@9: rt300@9: MessageOrganiser::init(cs,ts); rt300@11: rt300@11: TickListenerFunction callback; rt300@11: callback = boost::bind(&TrainingMessageOrganiser::onNextTick, this, _1); rt300@11: candidateSynth.registerForTicks(callback); rt300@12: rt300@14: numParamsToUse = 3; rt300@14: rt300@11: } rt300@14: rt300@9: void setupDefaultMapping(){ rt300@9: vector mappingIDsForChangeableParams = getMappingIDsFromSynths(); rt300@9: rt300@9: controlPanelType cpt = REVISITABLE; rt300@9: vector elemList; rt300@14: for(int i = 0; i < numParamsToUse; i++){ rt300@9: elemList.push_back(SLIDER); rt300@9: } rt300@9: rt300@9: vector UIElemHandles = panel->generateControls(elemList, cpt); rt300@9: rt300@9: mapSlidersToParams(UIElemHandles, mappingIDsForChangeableParams); rt300@9: rt300@9: bottomPanel->show(); rt300@9: } rt300@9: rt300@9: vector getMappingIDsFromSynths(){ rt300@9: vector index; rt300@14: for(int i = 0; i < numParamsToUse; i++){ rt300@9: index.push_back(i); rt300@9: } rt300@9: vector mids = candidateSynth.getMappingIDForIndices(index); rt300@9: rt300@9: return mids; rt300@9: } rt300@9: rt300@9: void setupNewTest(){ rt300@14: rt300@9: rt300@9: }; rt300@10: rt300@12: void setIconPanel(IconPanel * ip){ rt300@12: presetIconPanel = ip; rt300@12: } rt300@14: void setInstructionPanel(TextPanel * ip){ rt300@14: instructionPanel = ip; rt300@14: instructionPanel->show(); rt300@14: } rt300@14: //----------------------------------------------------------------------- rt300@14: void displayInstructions(Step s){ rt300@14: rt300@14: rt300@14: if (s.type == Step::COUNT_IN){ rt300@14: instructionPanel->setText("GET READY"); rt300@14: } rt300@14: if (s.type == Step::PREVIEW_DISPLAY){ rt300@14: instructionPanel->setText("MEMORISE"); rt300@14: panel->setColor(ofColor(0,0,0)); rt300@14: } rt300@14: if (s.type == Step::PREVIEW_PLAY){ rt300@14: instructionPanel->setText("MEMORISE"); rt300@14: panel->setColor(ofColor(0,0,0)); rt300@14: } rt300@14: if (s.type == Step::MATCHING_INTERACTION){ rt300@14: instructionPanel->setText("MATCH:"); rt300@14: panel->setColor(ofColor(100,0,0)); rt300@14: } rt300@14: if (s.type == Step::MATCHING_RESULT){ rt300@14: instructionPanel->setText("RESULT"); rt300@14: panel->setColor(ofColor(0,100,0)); rt300@14: } rt300@14: } rt300@14: //----------------------------------------------------------------------- rt300@10: void onNextTick(int tickNumber){ rt300@11: cout << "TICK " << tickNumber << endl; rt300@14: rt300@14: // only first beat in bar is active one rt300@14: if ( tickNumber % 4 != 0){ rt300@14: return; rt300@14: } rt300@14: // load next target preset rt300@11: rt300@14: Step newStep = sequenceController.getNextStep(); rt300@14: displayInstructions(newStep); rt300@14: rt300@14: if(newStep.isLastOfAll){ rt300@14: // do finished run stuff, show summary rt300@14: candidateSynth.stopMetronome(); rt300@14: cout << "FINISHED BLOCK" << endl; rt300@10: } rt300@14: if(newStep.isLastOfRun){ rt300@13: // do finished run stuff, show summary rt300@13: candidateSynth.stopMetronome(); rt300@13: cout << "FINISHED RUN" << endl; rt300@13: } rt300@14: rt300@14: float t = newStep.getTimeBetweenTicks(); rt300@14: candidateSynth.setMetroTime(t); rt300@14: rt300@14: if(newStep.type == Step::COUNT_IN){ rt300@14: // count in rt300@14: return; rt300@13: } rt300@14: rt300@14: if(newStep.presetIndex >= 0 && newStep.presetIndex <= 8){ rt300@14: currentTargetPreset = expPresetManager.getPreset(newStep.presetIndex); rt300@14: } rt300@14: rt300@14: if(newStep.showsTargetIcon){ rt300@14: presetIconPanel->setTextAndImage(currentTargetPreset->name, currentTargetPreset->getImage()); rt300@14: presetIconPanel->show(); rt300@14: }else{ rt300@14: presetIconPanel->hide(); rt300@14: } rt300@14: rt300@14: if(newStep.showsControlSettings){ rt300@14: targetSynth.setAllParams(currentTargetPreset->getValues()); rt300@14: setSlidersToTarget(); rt300@14: rt300@14: }else{ rt300@14: //setSlidersToDefault(); rt300@14: rt300@14: } rt300@14: rt300@14: if(newStep.playsTarget){ rt300@14: targetSynth.setAllParams(currentTargetPreset->getValues()); rt300@14: targetSynth.trigger(); rt300@14: } rt300@14: rt300@14: if(newStep.playsCandidate){ rt300@14: triggerCandidateSound(); rt300@14: } rt300@14: rt300@14: if(newStep.allowsCandidateControl){ rt300@14: panel->setActive(true); rt300@14: }else{ rt300@14: panel->setActive(false); rt300@14: } rt300@14: rt300@14: if(newStep.showsMatchResults){ rt300@14: // do something rt300@14: } rt300@14: rt300@14: if(newStep.showsControlGuides){ rt300@14: rt300@14: panel->setHintValues(currentTargetPreset->getValues()); rt300@14: panel->showHint(true); rt300@14: }else{ rt300@14: panel->showHint(false); rt300@14: } rt300@14: rt300@10: } rt300@14: rt300@14: //----------------------------------------------------------------------- rt300@9: protected: rt300@12: void showUserHowTheyDid(){ rt300@12: // colour flash rt300@12: // distance ? rt300@12: // score rt300@12: rt300@12: } rt300@10: void loadPreset(string pname){ rt300@10: rt300@10: vector values = expPresetManager.recallPreset(pname); rt300@10: if (values.size()){ rt300@10: candidateSynth.setAllParams(values); rt300@10: setAllSlidersToValues(values); rt300@10: }else{ rt300@10: cout << "ERROR, no preset found" << endl; rt300@10: } rt300@10: } rt300@10: rt300@10: rt300@14: //----------------------------------------------------------------------- rt300@10: void showATargetPresetWithGuide(Preset * p){ // this is when demoing the sequence to the user rt300@10: // p.show icon rt300@10: vector values = p->getValues(); rt300@10: if (values.size()){ rt300@10: candidateSynth.setAllParams(values); rt300@10: setAllSlidersToValues(values); rt300@10: }else{ rt300@10: cout << "WARNING, preset to show had no values" << endl; rt300@10: } rt300@10: } rt300@14: //----------------------------------------------------------------------------- rt300@10: rt300@9: void mapSlidersToParams(vector elems, vector mids){ rt300@9: rt300@9: vector::iterator elit; rt300@9: vector typeListLog; rt300@9: int i = 0; rt300@9: for(elit=elems.begin(); elitgetType() == SLIDER){ rt300@9: if(i >= mids.size()){ rt300@9: rt300@9: cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl; rt300@9: } rt300@9: rt300@9: ButtronSlider* theSlider = (ButtronSlider*)(*elit); rt300@9: mapControlToParam((*elit), mids[i]); rt300@9: theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i])); rt300@9: cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl; rt300@9: theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i]))); rt300@9: i++; rt300@9: typeListLog.push_back(int(SLIDER)); rt300@9: rt300@9: }else{ rt300@9: cout << "ERROR ERROR: ui type not handled my mapping function !" << endl; rt300@9: } rt300@9: } rt300@9: rt300@9: eventLogger.logEvent(CONTROL_LIST,typeListLog); rt300@9: }; rt300@14: //----------------------------------------------------------------------------- rt300@9: rt300@9: void buttonPressCallback(int mappingID, int value){ rt300@9: if(mappingID == VOLUME_CHANGE_ID){ rt300@9: targetSynth.sendVolume(value); rt300@9: candidateSynth.sendVolume(value); rt300@10: return; rt300@9: } rt300@14: rt300@9: if (mappingID == TRIGGER_CANDIDATE_ID){ rt300@14: //triggerCandidateSound(); rt300@10: // compare to target rt300@14: candidateSynth.setMetroTime(sequenceController.getStartTickTime()); rt300@11: candidateSynth.startMetronome(); rt300@10: return; rt300@10: } rt300@10: if(mappingID == SAVE_PRESET_HIT){ rt300@10: expPresetManager.savePreset("blah", candidateSynth.getAllParamValues()); rt300@10: return; rt300@10: } rt300@10: if(mappingID == RECALL_PRESET_HIT){ rt300@10: rt300@10: loadPreset("blah"); rt300@9: return; rt300@9: } rt300@9: } rt300@14: //----------------------------------------------------------------------------- rt300@14: rt300@10: SequenceController sequenceController; rt300@10: bool sequencePreview; rt300@10: Preset * currentTargetPreset; rt300@12: IconPanel* presetIconPanel; rt300@14: TextPanel* instructionPanel; rt300@8: }; rt300@8: #endif /* defined(__riftathon__TrainingMessageOrganiser__) */