rt300@0: // rt300@0: // MessageOrganiser.h rt300@0: // tweakathlon rt300@0: // rt300@0: // Created by Robert Tubb on 10/12/2013. rt300@0: // rt300@0: // This object handles the mapping from GUI to params rt300@0: // rt300@0: // and sends their messages to PD and eventLogger rt300@0: #pragma once rt300@0: #include "eventLogger.h" rt300@0: #include rt300@0: #include rt300@0: #include rt300@0: #include "boost/bind.hpp" rt300@0: #include "boost/function.hpp" rt300@0: rt300@0: #include rt300@0: #include rt300@0: #include rt300@0: #include rt300@0: #include "AppCore.h" rt300@0: #include "ofxPd.h" rt300@0: #include "TestController.h" rt300@0: #include "timeController.h" rt300@0: #include "PDSynthWrapper.h" rt300@0: #include "ofxTimer.h" rt300@0: #include "sliderPanel.h" rt300@0: //#include "testApp.h" rt300@0: #include "targetSymbol.h" rt300@0: #include "3Dbox.h" rt300@0: #include "TextPanel.h" rt300@0: #include "CountdownText.h" rt300@0: #include "buttonPanel.h" rt300@6: #include "ExplorePresetManager.h" rt300@6: rt300@6: rt300@6: // should be called TIMED TEST MESSAGE ORGANISER ? rt300@0: rt300@0: // event logger needs to know rt300@0: // which controls were showing in what mode rt300@0: // which controls were mapped to what param rt300@0: // what was the target sound params rt300@0: // all the updates of control movements, submit, quit etc rt300@0: rt300@0: // this is the bit that handles mapping from UI elements to synth i.e testApp DOESNT DO THAT rt300@0: rt300@0: // has links to panel sliders can show hide them rt300@0: rt300@0: // controls flow of stuff rt300@0: rt300@0: //--------------------------------------------------------------------- rt300@0: //--------------------------------------------------------------------- rt300@0: extern TimeController timeController; rt300@0: rt300@0: extern EventLogger eventLogger; rt300@0: rt300@6: extern ExplorePresetManager expPresetManager; rt300@4: rt300@0: typedef boost::function AppModeChangeFunction; rt300@0: rt300@0: class MessageOrganiser { rt300@0: private: rt300@0: AppCore* core; rt300@0: //testApp* theOFApp; rt300@0: PDSynthWrapper targetSynth; rt300@0: PDSynthWrapper candidateSynth; rt300@0: rt300@0: map currentMapping; // could get more sophisticated if not 1-1 ? rt300@0: rt300@0: SliderPanel* panel; rt300@0: TimeController altPlaybackController; rt300@0: rt300@0: TestController* testController; rt300@0: Buttron* newTestButton; rt300@0: //Buttron* submitButton; rt300@0: rt300@0: ButtonPanel* bottomPanel; // shows during test : play buttons and submit rt300@0: Buttron* targetPlayButton; // so we can hide target in memory test. this pointer stuff is getting out of hand rt300@0: CountdownText* countdownPanel; rt300@0: TargetSymbol* targetSymbol; rt300@0: Leap3DBoxGL* box3D; rt300@0: TextPanel* scorePanel; rt300@0: TextPanel* finishPanel; rt300@0: AppModeChangeFunction testAppModeChange; rt300@0: rt300@0: //int scoreRunningTotal; rt300@0: TimerID currentSoundPlayTimer; rt300@0: rt300@0: int alternationSpeed; // ms between cand and target rt300@0: bool playingAlternating; rt300@0: rt300@0: bool okToGetLeapMidi; rt300@0: rt300@0: void testsFinished(){ rt300@0: panel->hide(); rt300@0: bottomPanel->hide(); rt300@0: newTestButton->hide(); rt300@0: rt300@0: vector eData; rt300@0: eData.push_back(testController->getScoreRunningTotal()); rt300@0: eventLogger.logEvent(ALL_TESTS_COMPLETED, eData); rt300@0: rt300@0: // TODO set final score screen txt to testController->getScoreRunningTotal() rt300@0: finishPanel->show(); rt300@0: rt300@0: string user = eventLogger.getUsername(); rt300@0: stringstream s; rt300@0: s << "Experiment completed" rt300@0: << endl << endl rt300@0: << "You scored: " << testController->getScoreRunningTotal() << " well done " << user << endl << endl rt300@0: << "to retake test please close " << endl << endl rt300@0: << "the app and restart with username"; rt300@0: finishPanel->setText(s.str()); rt300@0: // get test app to do something... rt300@0: rt300@0: eventLogger.saveSessionToFile(); rt300@0: }; rt300@0: rt300@0: void setupNewTest(){ rt300@0: // get mapping for new test and make sure we have right controls and stuff rt300@0: rt300@0: rt300@0: Test newTest = testController->goToNextTest(); rt300@0: rt300@0: // V0.2 put details about what kind of test it is rt300@0: vector eData; rt300@0: eData.push_back(newTest.isPractice()); rt300@0: eData.push_back(newTest.isWithHint()); rt300@0: eData.push_back(newTest.isMemoryTest()); rt300@0: eventLogger.logEvent(NEW_TEST, eData); rt300@0: rt300@0: rt300@0: vector mappingIDsForChangeableParams = setSynthsUpForNewTest(newTest); rt300@0: rt300@0: vector UIElemHandles = panel->generateControls(testController->getCurrentListOfControls(), testController->getCurrentPanelType()); rt300@0: rt300@0: mapUIToNewTestParams(UIElemHandles, mappingIDsForChangeableParams); rt300@0: rt300@0: countdownPanel->setTestTypeString(newTest.getTestTypeAdvanceWarning()); rt300@0: rt300@0: rt300@0: }; rt300@0: void startNewTest(){ rt300@0: Test t = testController->getCurrentTest(); rt300@0: rt300@0: countdownPanel->hide(); rt300@0: panel->show(); rt300@0: panel->setActive(true); rt300@0: if(t.isWithHint()){ rt300@0: panel->showHint(true); rt300@0: } rt300@0: rt300@0: bottomPanel->show(); rt300@0: targetPlayButton->show(); // incase it was memory test rt300@0: if (t.isMemoryTest()){ rt300@0: targetPlayButton->setLabel("Memorise!"); rt300@0: }else{ rt300@0: targetPlayButton->setLabel("Target"); rt300@0: } rt300@0: //startAlternatingPlayback(); rt300@0: //timeController.scheduleEvent(boost::bind(&MessageOrganiser::sendSynthValuesAgain, this), 200); rt300@0: timeController.startStopwatch(); rt300@0: eventLogger.logEvent(TEST_TIMER_STARTED); rt300@0: rt300@0: rt300@0: if(t.getListOfControlTypes()[0] == LEAP3D){ rt300@0: okToGetLeapMidi = true; rt300@0: } rt300@0: }; rt300@0: rt300@0: vector setSynthsUpForNewTest(Test newTest){ rt300@0: targetSynth.setAllParams(newTest.getTargetValues()); rt300@0: eventLogger.logEvent(TARGET_PARAM_SET, newTest.getTargetValues()); // unless something goes wrong in setAllParams rt300@0: rt300@0: candidateSynth.setAllParams(newTest.getStartingCandidateValues()); rt300@0: eventLogger.logEvent(CANDIDATE_PARAM_SET,newTest.getStartingCandidateValues()); rt300@0: rt300@0: // eventLogger.logEvent(NEW_TARGET_PARAMS, vector ); rt300@0: // eventLogger.logEvent(NEW_CANDIDATE_PARAMS, vector ); rt300@0: rt300@0: vector mids = candidateSynth.getMappingIDForIndices(newTest.getChangeableIndices()); rt300@0: rt300@0: eventLogger.logEvent(CANDIDATE_CHANGEABLE_IDX, newTest.getChangeableIndices()); rt300@0: eventLogger.logEvent(CANDIDATE_MAPPING_IDS, mids); rt300@0: rt300@0: return mids; rt300@0: }; rt300@0: void sendSynthValuesAgain(){ rt300@0: candidateSynth.sendAllParams(); rt300@0: targetSynth.sendAllParams(); rt300@0: }; rt300@0: rt300@0: // could have been cleverer. takes forever due to searching ??? rt300@0: void mapUIToNewTestParams(vector elems, vector mids){ rt300@0: rt300@0: vector::iterator elit; rt300@0: vector typeListLog; rt300@0: int i = 0; rt300@0: for(elit=elems.begin(); elitgetType() == XYPAD){ rt300@0: if(i+1 >= mids.size()){ rt300@0: cout << "ERROR ERROR: too many controls for mapping IDs" << endl; rt300@0: } rt300@0: rt300@0: ButtronXY* theXY = (ButtronXY*)(*elit); rt300@0: mapXYToParams(theXY, mids[i], mids[i+1]); rt300@0: theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1])); rt300@0: theXY->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) rt300@0: ,targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i+1]))); rt300@0: i+=2; rt300@0: typeListLog.push_back(int(XYPAD)); rt300@0: }else if ( (*elit)->getType() == SLIDER){ rt300@0: if(i >= mids.size()){ rt300@2: rt300@2: cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl; rt300@0: } rt300@0: rt300@0: ButtronSlider* theSlider = (ButtronSlider*)(*elit); rt300@0: mapControlToParam((*elit), mids[i]); rt300@0: theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i])); rt300@0: cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl; rt300@0: theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i]))); rt300@0: i++; rt300@0: typeListLog.push_back(int(SLIDER)); rt300@0: }else if ( (*elit)->getType() == LEAP3D ){ rt300@0: set3Dbox((Leap3DBoxGL*)(*elit)); rt300@0: // UH rt300@0: string nameX = candidateSynth.getNameForMappingID(mids[i]); rt300@0: box3D->setHintValue(0,targetSynth.getParamValueFromName(nameX)); rt300@0: box3D->setValueAndScale(0, candidateSynth.getParamValueForID(mids[i])); rt300@0: i++; rt300@0: rt300@0: string nameY = candidateSynth.getNameForMappingID(mids[i]); rt300@0: box3D->setHintValue(1,targetSynth.getParamValueFromName(nameY)); rt300@0: box3D->setValueAndScale(1, candidateSynth.getParamValueForID(mids[i])); rt300@0: i++; rt300@0: rt300@0: string nameZ = candidateSynth.getNameForMappingID(mids[i]); rt300@0: box3D->setHintValue(2,targetSynth.getParamValueFromName(nameZ)); rt300@0: box3D->setValueAndScale(2, candidateSynth.getParamValueForID(mids[i])); rt300@0: i++; rt300@0: rt300@0: rt300@0: box3D->setLabels(nameX,nameY,nameZ); rt300@0: typeListLog.push_back(int(LEAP3D)); rt300@0: rt300@0: }else{ rt300@0: cout << "ERROR ERROR: ui type not handled my mapping function !" << endl; rt300@0: } rt300@0: } rt300@0: rt300@0: eventLogger.logEvent(CONTROL_LIST,typeListLog); rt300@0: }; rt300@0: rt300@0: // TODO - no, triggering playback needs to be logged rt300@0: void startAlternatingPlayback(){ rt300@0: rt300@0: cout << "start alt playback" << endl; rt300@0: // use our special timer to fire off play to pd rt300@0: // sets off timed alternating playback rt300@0: rt300@0: playAlternating(); rt300@0: playingAlternating = true; rt300@0: rt300@0: }; rt300@0: void stopAlternatingPlayback(){ rt300@0: cout << "stop alt playback" << endl; rt300@0: // kill the alternation rt300@0: timeController.cancelEvent(currentSoundPlayTimer); rt300@0: playingAlternating = false; rt300@0: }; rt300@0: rt300@0: void playAlternating(){ rt300@0: rt300@0: static bool alt; rt300@0: int nextTime; rt300@0: if (alt){ rt300@0: targetSynth.trigger(); rt300@0: // flash the target thingy rt300@0: targetSymbol->flash(); rt300@0: nextTime = alternationSpeed*1.503; // gap after target rt300@0: }else{ rt300@0: sendSynthValuesAgain(); // and again and again rt300@0: candidateSynth.trigger(); rt300@0: panel->flash(); rt300@0: nextTime = alternationSpeed; rt300@0: } rt300@0: alt = !alt; rt300@0: candidateSynth.setNoteLength(alternationSpeed); rt300@0: targetSynth.setNoteLength(alternationSpeed); // could be user alterable rt300@0: currentSoundPlayTimer = timeController.scheduleEvent(boost::bind(&MessageOrganiser::playAlternating,this), nextTime); rt300@0: rt300@0: rt300@0: rt300@0: }; rt300@0: rt300@0: void delayedShowNewTest(){ rt300@0: newTestButton->show(); rt300@0: // JUST IN CASE IT CRASHES near end... rt300@0: //eventLogger.saveSessionToFile(); rt300@0: }; rt300@0: void submitSingleControl(){ rt300@0: // if last one rt300@0: // submitPressed() rt300@0: rt300@0: // else rt300@0: rt300@0: // grey out that slider, rt300@0: // activate next slider and show it's button (same button but moved!???) rt300@0: rt300@0: }; rt300@0: rt300@0: rt300@0: void submitPressed(){ rt300@0: rt300@0: // depending on mode go to next control rt300@0: // if(testController->getCurrentPanelType() == SEQUENTIAL){ rt300@0: // submitSingleControl(); rt300@0: // return; rt300@0: // } rt300@0: // otherwise do this other - or call rt300@0: rt300@0: okToGetLeapMidi = false; rt300@0: rt300@0: TimerMillisec timeTaken = timeController.stopStopwatch(); rt300@0: vector answer = candidateSynth.getAllParamValues(); rt300@0: rt300@0: eventLogger.logEvent(SUBMIT_PRESSED, answer); //, answer, scoreRunningTotal, time taken (why not?)); rt300@0: rt300@0: TestResult result = testController->submitAnswer(answer, timeTaken); // TODO returns all the results rt300@0: rt300@0: vector logResult; rt300@0: logResult.push_back(result.realDistanceToTarget*1000); // measured in milliCC !??! rt300@0: logResult.push_back(result.timeTaken); // milliseconds rt300@0: logResult.push_back(result.score); rt300@0: logResult.push_back(result.targetBandHit); rt300@0: logResult.push_back(result.timeWindowHit); rt300@0: rt300@0: eventLogger.logEvent(DISTANCE_TIME_SCORE, logResult); rt300@0: rt300@0: rt300@0: // gui stuff - different controller? rt300@0: panel->setActive(false); rt300@0: panel->showHint(true); // add some encouraging feedback to hint rt300@0: bottomPanel->hide(); rt300@0: rt300@0: showScoreForTest(result); rt300@0: rt300@0: stopAlternatingPlayback(); rt300@0: rt300@0: // was it the final sumbit? rt300@0: if(testController->isLastTest()){ rt300@0: // thats it - show a final score screen etc rt300@0: timeController.scheduleEvent(boost::bind(&MessageOrganiser::testsFinished, this), 500); rt300@0: return; rt300@0: }else{ rt300@0: timeController.scheduleEvent(boost::bind(&MessageOrganiser::delayedShowNewTest, this), 300); rt300@0: } rt300@0: rt300@0: rt300@0: }; rt300@0: rt300@0: void showScoreForTest(TestResult result){ rt300@0: scorePanel->setText(result.displayText); rt300@0: scorePanel->show(); rt300@0: rt300@0: ofColor c; rt300@0: if(result.targetBandHit == 1){ rt300@0: // yellow red blue rt300@0: c = ofColor(255,255,0,255); rt300@0: }else if(result.targetBandHit == 2){ rt300@0: c = ofColor(255,0,0,255); rt300@0: }else if(result.targetBandHit == 3){ rt300@0: c = ofColor(45,45,255,255); rt300@0: }else if(result.targetBandHit == 4){ rt300@0: c = ofColor(0,255,0,255); rt300@0: }else{ rt300@0: c = ofColor(150,235,200,255); rt300@0: } rt300@0: scorePanel->setColor(c); rt300@0: panel->setHintColor(c); rt300@0: }; rt300@0: rt300@4: void setAllSlidersToValues(vector values){ rt300@4: for(int i = 0; i < values.size(); i++){ rt300@4: setUIToParam(i, values[i]); rt300@4: } rt300@4: } rt300@0: // we want to set UI object rt300@0: void setUIToParam(int index, int value){ // e.g. from MIDI incoming, will handle both box and sliders... rt300@0: // theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1])); rt300@0: UIElement* elem; rt300@0: // get the element rt300@0: if(panel->subElements.size() <= index){ rt300@4: cout << "ERROR: index out of range for num sliders" << endl; rt300@0: return; rt300@0: } rt300@0: elem = panel->subElements[index]; rt300@0: if ( elem->getType() == SLIDER){ rt300@0: ButtronSlider* theSlider = (ButtronSlider*)elem; rt300@0: theSlider->setValueAndScale(value); rt300@0: rt300@0: }else{ rt300@0: cout << "ERROR ERROR: ui type not handled by setUIToParam!" << endl; rt300@0: } rt300@0: rt300@0: }; rt300@0: rt300@0: rt300@0: void mapControlToParam(UIElement* control, int mappingID){ rt300@0: rt300@0: UICallbackFunction callbackF; rt300@0: callbackF = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2); rt300@0: control->addHandler(callbackF, mappingID); rt300@0: // put in our map so we can send param values to gui rt300@0: currentMapping.insert(std::pair(mappingID,control)); rt300@0: cout << " Mapped control to ID: " << mappingID << "Name: " << candidateSynth.getNameForMappingID(mappingID) << endl; rt300@0: control->setLabel(candidateSynth.getNameForMappingID(mappingID)); rt300@0: }; rt300@0: rt300@0: void mapXYToParams(ButtronXY* control, int mappingIDX, int mappingIDY){ rt300@0: UICallbackFunction callback; rt300@0: rt300@0: callback = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2); rt300@0: rt300@0: control->addHandler(callback, mappingIDX, mappingIDY); rt300@0: rt300@0: // put in our map so we can send param values to gui rt300@0: //currentMapping.insert(std::pair(mappingID,control)); rt300@0: rt300@0: rt300@0: cout << " Mapped control to XID: " << mappingIDX << "Name: " << candidateSynth.getNameForMappingID(mappingIDX) << endl; rt300@0: cout << " Mapped control to YID: " << mappingIDY << "Name: " << candidateSynth.getNameForMappingID(mappingIDY) << endl; rt300@0: control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY)); rt300@0: rt300@0: }; rt300@0: rt300@0: void mapLeapToParams(ButtronXY* control, int mappingIDX, int mappingIDY, int mappingIDZ){ rt300@0: // UICallbackFunction callbackX; rt300@0: // UICallbackFunction callbackY; rt300@0: // UICallbackFunction callbackZ; rt300@0: // rt300@0: // callbackX = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2); rt300@0: // callbackY = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2); rt300@0: // callbackZ = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2); rt300@0: // rt300@0: // control->addHandler(callbackX, mappingIDX); rt300@0: // control->addHandler(callbackY, mappingIDY); rt300@0: // rt300@0: // // put in our map so we can send param values to gui rt300@0: // //currentMapping.insert(std::pair(mappingID,control)); rt300@0: // rt300@0: // rt300@0: // cout << " Mapped control to XID: " << mappingIDX << "Name: " << candidateSynth.getNameForMappingID(mappingIDX) << endl; rt300@0: // cout << " Mapped control to YID: " << mappingIDY << "Name: " << candidateSynth.getNameForMappingID(mappingIDY) << endl; rt300@0: // control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY)); rt300@0: rt300@0: }; rt300@0: rt300@0: void mapControlToParam(UIElement* control, string paramName){ rt300@0: // get mapping ID from synth rt300@0: int mappingID = candidateSynth.getMappingIDForName(paramName); rt300@0: mapControlToParam(control, mappingID); rt300@0: control->setLabel(paramName); rt300@0: }; rt300@0: public: rt300@0: void init(AppCore* aCore, TestController* tc){ rt300@0: // set PD core... rt300@0: rt300@0: core = aCore; rt300@0: targetSynth.init(aCore,"targetSynth"); rt300@0: candidateSynth.init(aCore,"candidateSynth"); rt300@0: rt300@0: testController = tc; rt300@0: currentSoundPlayTimer = -1; rt300@0: okToGetLeapMidi = false; rt300@0: rt300@0: alternationSpeed = 200; rt300@0: rt300@0: candidateSynth.setNoteLength(alternationSpeed); rt300@0: targetSynth.setNoteLength(alternationSpeed); rt300@0: rt300@0: playingAlternating = false; rt300@0: }; rt300@0: void setNewTestButton(Buttron * ntb){ rt300@0: newTestButton = ntb; rt300@0: }; rt300@0: void set3Dbox(Leap3DBoxGL* box){ rt300@0: box3D = box; rt300@0: }; rt300@0: void setBottomPanel(ButtonPanel * ntb){ rt300@0: bottomPanel = ntb; rt300@0: }; rt300@0: void setControlPanel(SliderPanel* p){ rt300@0: panel = p; rt300@0: rt300@0: }; rt300@0: void setCountdownPanel(CountdownText* cd){ rt300@0: countdownPanel = cd; rt300@0: }; rt300@0: void setTargetSymbol(TargetSymbol* ts){ rt300@0: targetSymbol = ts; rt300@0: }; rt300@0: void setScorePanel(TextPanel* tp){ rt300@0: scorePanel = tp; rt300@0: }; rt300@0: void setFinishPanel(TextPanel* fp){ rt300@0: finishPanel = fp; rt300@0: } rt300@0: void setTargetButton(Buttron* tb){ rt300@0: targetPlayButton = tb; rt300@0: } rt300@0: int getScore(){ rt300@0: return testController->getScoreRunningTotal(); rt300@0: }; rt300@0: rt300@0: pair getTime(){ rt300@0: TimerMillisec tms = timeController.getStopwatchElapsedTime(); rt300@0: int s = int(tms/1000); rt300@0: int hs = int((tms%1000)/10); rt300@0: pair p(s,hs); rt300@0: return p; rt300@0: }; rt300@0: void countdownToNewTest(){ rt300@0: rt300@0: panel->hide(); rt300@0: panel->setActive(false); rt300@0: scorePanel->hide(); rt300@0: bottomPanel->hide(); rt300@0: newTestButton->hide(); rt300@0: rt300@0: // set up stuff rt300@0: setupNewTest(); rt300@0: eventLogger.logEvent(COUNTDOWN_INITIATED); rt300@0: rt300@0: countdownPanel->showAndStart(3); rt300@0: rt300@0: timeController.scheduleEvent(boost::bind(&MessageOrganiser::startNewTest, this), 3000); rt300@0: rt300@0: }; rt300@0: void sendToGUI(vector paramsToMap){ rt300@0: // look up these ids in mapping table rt300@0: }; rt300@0: void saveGoodTest(Test t){ rt300@0: rt300@0: }; rt300@0: void playTargetButtonPressed(){ rt300@0: rt300@0: static int numPlays = 3; rt300@0: rt300@0: Test* t = testController->getCurrentTestPtr(); rt300@0: if (!t->checkTargetPlaysRemaining()){ rt300@0: cout << t->getTargetPlaysLeft() << endl; rt300@0: rt300@0: sendSynthValuesAgain(); rt300@0: targetSynth.trigger(); rt300@0: eventLogger.logEvent(TARGET_PLAYED); rt300@0: targetPlayButton->hide(); rt300@0: return; rt300@0: rt300@0: } rt300@0: cout << t->getTargetPlaysLeft() << endl; rt300@0: rt300@0: sendSynthValuesAgain(); rt300@0: targetSynth.trigger(); rt300@0: eventLogger.logEvent(TARGET_PLAYED); rt300@0: rt300@0: return; rt300@0: } rt300@0: void playCandidateButtonPressed(){ rt300@0: // rt300@0: } rt300@0: void buttonPressCallback(int mappingID, int value){ rt300@0: if(mappingID == VOLUME_CHANGE_ID){ rt300@0: targetSynth.sendVolume(value); rt300@0: candidateSynth.sendVolume(value); rt300@0: rt300@0: } rt300@0: if(mappingID == SPEED_CHANGE_ID){ rt300@0: alternationSpeed = 2*(140 - value); rt300@0: vector eData; rt300@0: eData.push_back(alternationSpeed); rt300@0: eventLogger.logEvent(SPEED_CHANGED, eData); rt300@0: } rt300@0: if(mappingID == NEW_TEST_ID){ rt300@0: countdownToNewTest(); rt300@0: return; rt300@0: } rt300@0: if (mappingID == START_ALTERNATE_ID){ rt300@0: if(!playingAlternating){ rt300@0: startAlternatingPlayback(); rt300@0: rt300@0: }else{ rt300@0: stopAlternatingPlayback(); rt300@0: } rt300@0: return; rt300@0: } rt300@0: if(mappingID == GOOD_TEST_ID){ rt300@0: Test t = testController->getCurrentTest(); rt300@0: saveGoodTest(t); rt300@0: } rt300@0: if (mappingID == RANDOMISE_TARGET_ID){ // bleyeueurrrr rt300@0: targetSynth.randomiseParams(); rt300@0: return; rt300@0: } rt300@0: if (mappingID == TRIGGER_TARGET_ID){ rt300@0: playTargetButtonPressed(); rt300@0: rt300@0: } rt300@0: if (mappingID == TRIGGER_CANDIDATE_ID){ rt300@0: // log event rt300@0: sendSynthValuesAgain(); rt300@0: candidateSynth.trigger(); rt300@0: eventLogger.logEvent(CANDIDATE_PLAYED); rt300@0: // flash panel? rt300@0: panel->flash(); rt300@0: return; rt300@0: } rt300@0: if (mappingID == SUBMIT_CANDIDATE){ rt300@0: // log event rt300@0: submitPressed(); rt300@0: rt300@0: return; rt300@0: } rt300@0: if (mappingID == CRAP_TEST_ID){ rt300@0: // this is rubbish! send a log of target values, and mapping ids rt300@0: vector data; rt300@0: vector tvals = targetSynth.getAllParamValues(); rt300@0: vector pidx = testController->getCurrentChangeableParams(); rt300@0: data.insert(data.end(), tvals.begin(), tvals.end()); rt300@0: data.insert(data.end(), pidx.begin(), pidx.end()); rt300@0: rt300@0: eventLogger.logEvent(CRAP_TEST, data); rt300@0: } rt300@0: if(mappingID == SHOW_HIDE_PANEL){ rt300@0: static bool showing; rt300@0: rt300@0: if(showing){ rt300@0: cout << " showing"<show(); rt300@0: rt300@0: }else{ rt300@0: cout << " hiding"<hide(); rt300@0: } rt300@0: showing = !showing; rt300@0: } rt300@0: if(mappingID == SHOW_HIDE_HINT){ rt300@0: static bool showingHint; rt300@0: if(showingHint){ rt300@0: panel->showHint(false); rt300@0: showingHint = false; rt300@0: }else{ rt300@0: panel->showHint(true); rt300@0: showingHint = true; rt300@0: } rt300@0: } rt300@4: if(mappingID == SAVE_PRESET_HIT){ rt300@6: expPresetManager.savePreset("blah", candidateSynth.getAllParamValues()); rt300@4: rt300@4: } rt300@4: if(mappingID == RECALL_PRESET_HIT){ rt300@4: rt300@4: loadPreset("blah"); rt300@6: //candidateSynth.startMetronome(); rt300@4: rt300@4: } rt300@4: } rt300@4: void loadPreset(string pname){ rt300@4: rt300@6: vector values = expPresetManager.recallPreset(pname); rt300@5: if (values.size()){ rt300@4: candidateSynth.setAllParams(values); rt300@4: setAllSlidersToValues(values); rt300@5: }else{ rt300@5: cout << "ERROR, no preset found" << endl; rt300@5: } rt300@0: } rt300@0: // called from UI rt300@0: void paramChangeCallback(int mappingID, int value){ rt300@0: candidateSynth.paramChangeCallback(mappingID, value); rt300@0: vector evtData; rt300@0: evtData.push_back(mappingID); // or just index? rt300@0: evtData.push_back(value); rt300@0: rt300@0: eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData); rt300@0: }; rt300@0: rt300@0: // could template for ui element type?? rt300@0: void mapButtonToAction(UIElement* control, int mappingID){ rt300@0: UICallbackFunction callbackF; rt300@0: callbackF = boost::bind(&MessageOrganiser::buttonPressCallback, this, _1,_2); rt300@0: control->addHandler(callbackF, mappingID); rt300@0: currentMapping.insert(std::pair(mappingID,control)); rt300@0: } rt300@0: rt300@0: rt300@0: void midiFromLeap(int ctl_num, int ctl_val){ rt300@0: rt300@0: rt300@0: if (!okToGetLeapMidi){ rt300@0: return; rt300@0: } rt300@2: rt300@0: rt300@0: Test *theTest = testController->getCurrentTestPtr(); rt300@0: if (theTest == NULL) return; rt300@0: rt300@2: rt300@0: rt300@0: rt300@2: rt300@0: vector ci = theTest->getChangeableIndices(); rt300@0: vector mids = candidateSynth.getMappingIDForIndices(ci); rt300@0: if (ctl_num >= mids.size() || ctl_num < 0) return; rt300@0: rt300@0: candidateSynth.paramChangeCallback(mids[ctl_num], ctl_val); rt300@0: rt300@3: setUIToParam(ctl_num, ctl_val); rt300@2: rt300@0: vector evtData; rt300@0: evtData.push_back(mids[ctl_num]); // or just index? rt300@0: evtData.push_back(ctl_val); rt300@0: rt300@0: eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData); rt300@0: // also call UI object rt300@0: // get mapping ID for rt300@0: // setUIToParam(ctl_num, ctl_val); rt300@0: } rt300@3: // void setSlidersFromLeap(int i, int val){ rt300@3: // ButtronSlider* theSlider = (ButtronSlider*)panel->getSlider(i); rt300@3: // theSlider->setValueAndScale(val); rt300@3: // } rt300@3: rt300@3: rt300@3: rt300@3: void setSlidersToTarget(){ rt300@3: // this will actually show sliders with target vals - for "memorisation" purposes mwa heh heh rt300@3: // get target values rt300@3: // set ui rt300@3: vector vals = targetSynth.getAllParamValues(); rt300@3: for(int i=1; i < vals.size(); i++){ rt300@3: setUIToParam(i, vals[i]); rt300@3: } rt300@2: } rt300@0: rt300@0: }; rt300@0: