annotate MessageOrganiser.h @ 6:92850a2b099c

set up preset slots from init file. PD synth has metronome, recieves ticks but doesn't do anything with them.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Fri, 17 Oct 2014 14:50:50 +0100
parents 213df0baed47
children d59de9fd3496
rev   line source
rt300@0 1 //
rt300@0 2 // MessageOrganiser.h
rt300@0 3 // tweakathlon
rt300@0 4 //
rt300@0 5 // Created by Robert Tubb on 10/12/2013.
rt300@0 6 //
rt300@0 7 // This object handles the mapping from GUI to params
rt300@0 8 //
rt300@0 9 // and sends their messages to PD and eventLogger
rt300@0 10 #pragma once
rt300@0 11 #include "eventLogger.h"
rt300@0 12 #include <map.h>
rt300@0 13 #include <vector>
rt300@0 14 #include <string>
rt300@0 15 #include "boost/bind.hpp"
rt300@0 16 #include "boost/function.hpp"
rt300@0 17
rt300@0 18 #include <UIElement.h>
rt300@0 19 #include <Buttron.h>
rt300@0 20 #include <ButtronSlider.h>
rt300@0 21 #include <ButtronXY.h>
rt300@0 22 #include "AppCore.h"
rt300@0 23 #include "ofxPd.h"
rt300@0 24 #include "TestController.h"
rt300@0 25 #include "timeController.h"
rt300@0 26 #include "PDSynthWrapper.h"
rt300@0 27 #include "ofxTimer.h"
rt300@0 28 #include "sliderPanel.h"
rt300@0 29 //#include "testApp.h"
rt300@0 30 #include "targetSymbol.h"
rt300@0 31 #include "3Dbox.h"
rt300@0 32 #include "TextPanel.h"
rt300@0 33 #include "CountdownText.h"
rt300@0 34 #include "buttonPanel.h"
rt300@6 35 #include "ExplorePresetManager.h"
rt300@6 36
rt300@6 37
rt300@6 38 // should be called TIMED TEST MESSAGE ORGANISER ?
rt300@0 39
rt300@0 40 // event logger needs to know
rt300@0 41 // which controls were showing in what mode
rt300@0 42 // which controls were mapped to what param
rt300@0 43 // what was the target sound params
rt300@0 44 // all the updates of control movements, submit, quit etc
rt300@0 45
rt300@0 46 // this is the bit that handles mapping from UI elements to synth i.e testApp DOESNT DO THAT
rt300@0 47
rt300@0 48 // has links to panel sliders can show hide them
rt300@0 49
rt300@0 50 // controls flow of stuff
rt300@0 51
rt300@0 52 //---------------------------------------------------------------------
rt300@0 53 //---------------------------------------------------------------------
rt300@0 54 extern TimeController timeController;
rt300@0 55
rt300@0 56 extern EventLogger eventLogger;
rt300@0 57
rt300@6 58 extern ExplorePresetManager expPresetManager;
rt300@4 59
rt300@0 60 typedef boost::function<void(void)> AppModeChangeFunction;
rt300@0 61
rt300@0 62 class MessageOrganiser {
rt300@0 63 private:
rt300@0 64 AppCore* core;
rt300@0 65 //testApp* theOFApp;
rt300@0 66 PDSynthWrapper targetSynth;
rt300@0 67 PDSynthWrapper candidateSynth;
rt300@0 68
rt300@0 69 map<int,UIElement*> currentMapping; // could get more sophisticated if not 1-1 ?
rt300@0 70
rt300@0 71 SliderPanel* panel;
rt300@0 72 TimeController altPlaybackController;
rt300@0 73
rt300@0 74 TestController* testController;
rt300@0 75 Buttron* newTestButton;
rt300@0 76 //Buttron* submitButton;
rt300@0 77
rt300@0 78 ButtonPanel* bottomPanel; // shows during test : play buttons and submit
rt300@0 79 Buttron* targetPlayButton; // so we can hide target in memory test. this pointer stuff is getting out of hand
rt300@0 80 CountdownText* countdownPanel;
rt300@0 81 TargetSymbol* targetSymbol;
rt300@0 82 Leap3DBoxGL* box3D;
rt300@0 83 TextPanel* scorePanel;
rt300@0 84 TextPanel* finishPanel;
rt300@0 85 AppModeChangeFunction testAppModeChange;
rt300@0 86
rt300@0 87 //int scoreRunningTotal;
rt300@0 88 TimerID currentSoundPlayTimer;
rt300@0 89
rt300@0 90 int alternationSpeed; // ms between cand and target
rt300@0 91 bool playingAlternating;
rt300@0 92
rt300@0 93 bool okToGetLeapMidi;
rt300@0 94
rt300@0 95 void testsFinished(){
rt300@0 96 panel->hide();
rt300@0 97 bottomPanel->hide();
rt300@0 98 newTestButton->hide();
rt300@0 99
rt300@0 100 vector<int> eData;
rt300@0 101 eData.push_back(testController->getScoreRunningTotal());
rt300@0 102 eventLogger.logEvent(ALL_TESTS_COMPLETED, eData);
rt300@0 103
rt300@0 104 // TODO set final score screen txt to testController->getScoreRunningTotal()
rt300@0 105 finishPanel->show();
rt300@0 106
rt300@0 107 string user = eventLogger.getUsername();
rt300@0 108 stringstream s;
rt300@0 109 s << "Experiment completed"
rt300@0 110 << endl << endl
rt300@0 111 << "You scored: " << testController->getScoreRunningTotal() << " well done " << user << endl << endl
rt300@0 112 << "to retake test please close " << endl << endl
rt300@0 113 << "the app and restart with username<num test>";
rt300@0 114 finishPanel->setText(s.str());
rt300@0 115 // get test app to do something...
rt300@0 116
rt300@0 117 eventLogger.saveSessionToFile();
rt300@0 118 };
rt300@0 119
rt300@0 120 void setupNewTest(){
rt300@0 121 // get mapping for new test and make sure we have right controls and stuff
rt300@0 122
rt300@0 123
rt300@0 124 Test newTest = testController->goToNextTest();
rt300@0 125
rt300@0 126 // V0.2 put details about what kind of test it is
rt300@0 127 vector<int> eData;
rt300@0 128 eData.push_back(newTest.isPractice());
rt300@0 129 eData.push_back(newTest.isWithHint());
rt300@0 130 eData.push_back(newTest.isMemoryTest());
rt300@0 131 eventLogger.logEvent(NEW_TEST, eData);
rt300@0 132
rt300@0 133
rt300@0 134 vector<int> mappingIDsForChangeableParams = setSynthsUpForNewTest(newTest);
rt300@0 135
rt300@0 136 vector<UIElement*> UIElemHandles = panel->generateControls(testController->getCurrentListOfControls(), testController->getCurrentPanelType());
rt300@0 137
rt300@0 138 mapUIToNewTestParams(UIElemHandles, mappingIDsForChangeableParams);
rt300@0 139
rt300@0 140 countdownPanel->setTestTypeString(newTest.getTestTypeAdvanceWarning());
rt300@0 141
rt300@0 142
rt300@0 143 };
rt300@0 144 void startNewTest(){
rt300@0 145 Test t = testController->getCurrentTest();
rt300@0 146
rt300@0 147 countdownPanel->hide();
rt300@0 148 panel->show();
rt300@0 149 panel->setActive(true);
rt300@0 150 if(t.isWithHint()){
rt300@0 151 panel->showHint(true);
rt300@0 152 }
rt300@0 153
rt300@0 154 bottomPanel->show();
rt300@0 155 targetPlayButton->show(); // incase it was memory test
rt300@0 156 if (t.isMemoryTest()){
rt300@0 157 targetPlayButton->setLabel("Memorise!");
rt300@0 158 }else{
rt300@0 159 targetPlayButton->setLabel("Target");
rt300@0 160 }
rt300@0 161 //startAlternatingPlayback();
rt300@0 162 //timeController.scheduleEvent(boost::bind(&MessageOrganiser::sendSynthValuesAgain, this), 200);
rt300@0 163 timeController.startStopwatch();
rt300@0 164 eventLogger.logEvent(TEST_TIMER_STARTED);
rt300@0 165
rt300@0 166
rt300@0 167 if(t.getListOfControlTypes()[0] == LEAP3D){
rt300@0 168 okToGetLeapMidi = true;
rt300@0 169 }
rt300@0 170 };
rt300@0 171
rt300@0 172 vector<int> setSynthsUpForNewTest(Test newTest){
rt300@0 173 targetSynth.setAllParams(newTest.getTargetValues());
rt300@0 174 eventLogger.logEvent(TARGET_PARAM_SET, newTest.getTargetValues()); // unless something goes wrong in setAllParams
rt300@0 175
rt300@0 176 candidateSynth.setAllParams(newTest.getStartingCandidateValues());
rt300@0 177 eventLogger.logEvent(CANDIDATE_PARAM_SET,newTest.getStartingCandidateValues());
rt300@0 178
rt300@0 179 // eventLogger.logEvent(NEW_TARGET_PARAMS, vector<int> );
rt300@0 180 // eventLogger.logEvent(NEW_CANDIDATE_PARAMS, vector<int> );
rt300@0 181
rt300@0 182 vector<int> mids = candidateSynth.getMappingIDForIndices(newTest.getChangeableIndices());
rt300@0 183
rt300@0 184 eventLogger.logEvent(CANDIDATE_CHANGEABLE_IDX, newTest.getChangeableIndices());
rt300@0 185 eventLogger.logEvent(CANDIDATE_MAPPING_IDS, mids);
rt300@0 186
rt300@0 187 return mids;
rt300@0 188 };
rt300@0 189 void sendSynthValuesAgain(){
rt300@0 190 candidateSynth.sendAllParams();
rt300@0 191 targetSynth.sendAllParams();
rt300@0 192 };
rt300@0 193
rt300@0 194 // could have been cleverer. takes forever due to searching ???
rt300@0 195 void mapUIToNewTestParams(vector<UIElement*> elems, vector<int> mids){
rt300@0 196
rt300@0 197 vector<UIElement*>::iterator elit;
rt300@0 198 vector<int> typeListLog;
rt300@0 199 int i = 0;
rt300@0 200 for(elit=elems.begin(); elit<elems.end();elit++){
rt300@0 201 if ( (*elit)->getType() == XYPAD){
rt300@0 202 if(i+1 >= mids.size()){
rt300@0 203 cout << "ERROR ERROR: too many controls for mapping IDs" << endl;
rt300@0 204 }
rt300@0 205
rt300@0 206 ButtronXY* theXY = (ButtronXY*)(*elit);
rt300@0 207 mapXYToParams(theXY, mids[i], mids[i+1]);
rt300@0 208 theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1]));
rt300@0 209 theXY->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i]))
rt300@0 210 ,targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i+1])));
rt300@0 211 i+=2;
rt300@0 212 typeListLog.push_back(int(XYPAD));
rt300@0 213 }else if ( (*elit)->getType() == SLIDER){
rt300@0 214 if(i >= mids.size()){
rt300@2 215
rt300@2 216 cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl;
rt300@0 217 }
rt300@0 218
rt300@0 219 ButtronSlider* theSlider = (ButtronSlider*)(*elit);
rt300@0 220 mapControlToParam((*elit), mids[i]);
rt300@0 221 theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i]));
rt300@0 222 cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl;
rt300@0 223 theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])));
rt300@0 224 i++;
rt300@0 225 typeListLog.push_back(int(SLIDER));
rt300@0 226 }else if ( (*elit)->getType() == LEAP3D ){
rt300@0 227 set3Dbox((Leap3DBoxGL*)(*elit));
rt300@0 228 // UH
rt300@0 229 string nameX = candidateSynth.getNameForMappingID(mids[i]);
rt300@0 230 box3D->setHintValue(0,targetSynth.getParamValueFromName(nameX));
rt300@0 231 box3D->setValueAndScale(0, candidateSynth.getParamValueForID(mids[i]));
rt300@0 232 i++;
rt300@0 233
rt300@0 234 string nameY = candidateSynth.getNameForMappingID(mids[i]);
rt300@0 235 box3D->setHintValue(1,targetSynth.getParamValueFromName(nameY));
rt300@0 236 box3D->setValueAndScale(1, candidateSynth.getParamValueForID(mids[i]));
rt300@0 237 i++;
rt300@0 238
rt300@0 239 string nameZ = candidateSynth.getNameForMappingID(mids[i]);
rt300@0 240 box3D->setHintValue(2,targetSynth.getParamValueFromName(nameZ));
rt300@0 241 box3D->setValueAndScale(2, candidateSynth.getParamValueForID(mids[i]));
rt300@0 242 i++;
rt300@0 243
rt300@0 244
rt300@0 245 box3D->setLabels(nameX,nameY,nameZ);
rt300@0 246 typeListLog.push_back(int(LEAP3D));
rt300@0 247
rt300@0 248 }else{
rt300@0 249 cout << "ERROR ERROR: ui type not handled my mapping function !" << endl;
rt300@0 250 }
rt300@0 251 }
rt300@0 252
rt300@0 253 eventLogger.logEvent(CONTROL_LIST,typeListLog);
rt300@0 254 };
rt300@0 255
rt300@0 256 // TODO - no, triggering playback needs to be logged
rt300@0 257 void startAlternatingPlayback(){
rt300@0 258
rt300@0 259 cout << "start alt playback" << endl;
rt300@0 260 // use our special timer to fire off play to pd
rt300@0 261 // sets off timed alternating playback
rt300@0 262
rt300@0 263 playAlternating();
rt300@0 264 playingAlternating = true;
rt300@0 265
rt300@0 266 };
rt300@0 267 void stopAlternatingPlayback(){
rt300@0 268 cout << "stop alt playback" << endl;
rt300@0 269 // kill the alternation
rt300@0 270 timeController.cancelEvent(currentSoundPlayTimer);
rt300@0 271 playingAlternating = false;
rt300@0 272 };
rt300@0 273
rt300@0 274 void playAlternating(){
rt300@0 275
rt300@0 276 static bool alt;
rt300@0 277 int nextTime;
rt300@0 278 if (alt){
rt300@0 279 targetSynth.trigger();
rt300@0 280 // flash the target thingy
rt300@0 281 targetSymbol->flash();
rt300@0 282 nextTime = alternationSpeed*1.503; // gap after target
rt300@0 283 }else{
rt300@0 284 sendSynthValuesAgain(); // and again and again
rt300@0 285 candidateSynth.trigger();
rt300@0 286 panel->flash();
rt300@0 287 nextTime = alternationSpeed;
rt300@0 288 }
rt300@0 289 alt = !alt;
rt300@0 290 candidateSynth.setNoteLength(alternationSpeed);
rt300@0 291 targetSynth.setNoteLength(alternationSpeed); // could be user alterable
rt300@0 292 currentSoundPlayTimer = timeController.scheduleEvent(boost::bind(&MessageOrganiser::playAlternating,this), nextTime);
rt300@0 293
rt300@0 294
rt300@0 295
rt300@0 296 };
rt300@0 297
rt300@0 298 void delayedShowNewTest(){
rt300@0 299 newTestButton->show();
rt300@0 300 // JUST IN CASE IT CRASHES near end...
rt300@0 301 //eventLogger.saveSessionToFile();
rt300@0 302 };
rt300@0 303 void submitSingleControl(){
rt300@0 304 // if last one
rt300@0 305 // submitPressed()
rt300@0 306
rt300@0 307 // else
rt300@0 308
rt300@0 309 // grey out that slider,
rt300@0 310 // activate next slider and show it's button (same button but moved!???)
rt300@0 311
rt300@0 312 };
rt300@0 313
rt300@0 314
rt300@0 315 void submitPressed(){
rt300@0 316
rt300@0 317 // depending on mode go to next control
rt300@0 318 // if(testController->getCurrentPanelType() == SEQUENTIAL){
rt300@0 319 // submitSingleControl();
rt300@0 320 // return;
rt300@0 321 // }
rt300@0 322 // otherwise do this other - or call
rt300@0 323
rt300@0 324 okToGetLeapMidi = false;
rt300@0 325
rt300@0 326 TimerMillisec timeTaken = timeController.stopStopwatch();
rt300@0 327 vector<int> answer = candidateSynth.getAllParamValues();
rt300@0 328
rt300@0 329 eventLogger.logEvent(SUBMIT_PRESSED, answer); //, answer, scoreRunningTotal, time taken (why not?));
rt300@0 330
rt300@0 331 TestResult result = testController->submitAnswer(answer, timeTaken); // TODO returns all the results
rt300@0 332
rt300@0 333 vector<int> logResult;
rt300@0 334 logResult.push_back(result.realDistanceToTarget*1000); // measured in milliCC !??!
rt300@0 335 logResult.push_back(result.timeTaken); // milliseconds
rt300@0 336 logResult.push_back(result.score);
rt300@0 337 logResult.push_back(result.targetBandHit);
rt300@0 338 logResult.push_back(result.timeWindowHit);
rt300@0 339
rt300@0 340 eventLogger.logEvent(DISTANCE_TIME_SCORE, logResult);
rt300@0 341
rt300@0 342
rt300@0 343 // gui stuff - different controller?
rt300@0 344 panel->setActive(false);
rt300@0 345 panel->showHint(true); // add some encouraging feedback to hint
rt300@0 346 bottomPanel->hide();
rt300@0 347
rt300@0 348 showScoreForTest(result);
rt300@0 349
rt300@0 350 stopAlternatingPlayback();
rt300@0 351
rt300@0 352 // was it the final sumbit?
rt300@0 353 if(testController->isLastTest()){
rt300@0 354 // thats it - show a final score screen etc
rt300@0 355 timeController.scheduleEvent(boost::bind(&MessageOrganiser::testsFinished, this), 500);
rt300@0 356 return;
rt300@0 357 }else{
rt300@0 358 timeController.scheduleEvent(boost::bind(&MessageOrganiser::delayedShowNewTest, this), 300);
rt300@0 359 }
rt300@0 360
rt300@0 361
rt300@0 362 };
rt300@0 363
rt300@0 364 void showScoreForTest(TestResult result){
rt300@0 365 scorePanel->setText(result.displayText);
rt300@0 366 scorePanel->show();
rt300@0 367
rt300@0 368 ofColor c;
rt300@0 369 if(result.targetBandHit == 1){
rt300@0 370 // yellow red blue
rt300@0 371 c = ofColor(255,255,0,255);
rt300@0 372 }else if(result.targetBandHit == 2){
rt300@0 373 c = ofColor(255,0,0,255);
rt300@0 374 }else if(result.targetBandHit == 3){
rt300@0 375 c = ofColor(45,45,255,255);
rt300@0 376 }else if(result.targetBandHit == 4){
rt300@0 377 c = ofColor(0,255,0,255);
rt300@0 378 }else{
rt300@0 379 c = ofColor(150,235,200,255);
rt300@0 380 }
rt300@0 381 scorePanel->setColor(c);
rt300@0 382 panel->setHintColor(c);
rt300@0 383 };
rt300@0 384
rt300@4 385 void setAllSlidersToValues(vector<int> values){
rt300@4 386 for(int i = 0; i < values.size(); i++){
rt300@4 387 setUIToParam(i, values[i]);
rt300@4 388 }
rt300@4 389 }
rt300@0 390 // we want to set UI object
rt300@0 391 void setUIToParam(int index, int value){ // e.g. from MIDI incoming, will handle both box and sliders...
rt300@0 392 // theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1]));
rt300@0 393 UIElement* elem;
rt300@0 394 // get the element
rt300@0 395 if(panel->subElements.size() <= index){
rt300@4 396 cout << "ERROR: index out of range for num sliders" << endl;
rt300@0 397 return;
rt300@0 398 }
rt300@0 399 elem = panel->subElements[index];
rt300@0 400 if ( elem->getType() == SLIDER){
rt300@0 401 ButtronSlider* theSlider = (ButtronSlider*)elem;
rt300@0 402 theSlider->setValueAndScale(value);
rt300@0 403
rt300@0 404 }else{
rt300@0 405 cout << "ERROR ERROR: ui type not handled by setUIToParam!" << endl;
rt300@0 406 }
rt300@0 407
rt300@0 408 };
rt300@0 409
rt300@0 410
rt300@0 411 void mapControlToParam(UIElement* control, int mappingID){
rt300@0 412
rt300@0 413 UICallbackFunction callbackF;
rt300@0 414 callbackF = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
rt300@0 415 control->addHandler(callbackF, mappingID);
rt300@0 416 // put in our map so we can send param values to gui
rt300@0 417 currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
rt300@0 418 cout << " Mapped control to ID: " << mappingID << "Name: " << candidateSynth.getNameForMappingID(mappingID) << endl;
rt300@0 419 control->setLabel(candidateSynth.getNameForMappingID(mappingID));
rt300@0 420 };
rt300@0 421
rt300@0 422 void mapXYToParams(ButtronXY* control, int mappingIDX, int mappingIDY){
rt300@0 423 UICallbackFunction callback;
rt300@0 424
rt300@0 425 callback = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
rt300@0 426
rt300@0 427 control->addHandler(callback, mappingIDX, mappingIDY);
rt300@0 428
rt300@0 429 // put in our map so we can send param values to gui
rt300@0 430 //currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
rt300@0 431
rt300@0 432
rt300@0 433 cout << " Mapped control to XID: " << mappingIDX << "Name: " << candidateSynth.getNameForMappingID(mappingIDX) << endl;
rt300@0 434 cout << " Mapped control to YID: " << mappingIDY << "Name: " << candidateSynth.getNameForMappingID(mappingIDY) << endl;
rt300@0 435 control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY));
rt300@0 436
rt300@0 437 };
rt300@0 438
rt300@0 439 void mapLeapToParams(ButtronXY* control, int mappingIDX, int mappingIDY, int mappingIDZ){
rt300@0 440 // UICallbackFunction callbackX;
rt300@0 441 // UICallbackFunction callbackY;
rt300@0 442 // UICallbackFunction callbackZ;
rt300@0 443 //
rt300@0 444 // callbackX = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
rt300@0 445 // callbackY = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
rt300@0 446 // callbackZ = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
rt300@0 447 //
rt300@0 448 // control->addHandler(callbackX, mappingIDX);
rt300@0 449 // control->addHandler(callbackY, mappingIDY);
rt300@0 450 //
rt300@0 451 // // put in our map so we can send param values to gui
rt300@0 452 // //currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
rt300@0 453 //
rt300@0 454 //
rt300@0 455 // cout << " Mapped control to XID: " << mappingIDX << "Name: " << candidateSynth.getNameForMappingID(mappingIDX) << endl;
rt300@0 456 // cout << " Mapped control to YID: " << mappingIDY << "Name: " << candidateSynth.getNameForMappingID(mappingIDY) << endl;
rt300@0 457 // control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY));
rt300@0 458
rt300@0 459 };
rt300@0 460
rt300@0 461 void mapControlToParam(UIElement* control, string paramName){
rt300@0 462 // get mapping ID from synth
rt300@0 463 int mappingID = candidateSynth.getMappingIDForName(paramName);
rt300@0 464 mapControlToParam(control, mappingID);
rt300@0 465 control->setLabel(paramName);
rt300@0 466 };
rt300@0 467 public:
rt300@0 468 void init(AppCore* aCore, TestController* tc){
rt300@0 469 // set PD core...
rt300@0 470
rt300@0 471 core = aCore;
rt300@0 472 targetSynth.init(aCore,"targetSynth");
rt300@0 473 candidateSynth.init(aCore,"candidateSynth");
rt300@0 474
rt300@0 475 testController = tc;
rt300@0 476 currentSoundPlayTimer = -1;
rt300@0 477 okToGetLeapMidi = false;
rt300@0 478
rt300@0 479 alternationSpeed = 200;
rt300@0 480
rt300@0 481 candidateSynth.setNoteLength(alternationSpeed);
rt300@0 482 targetSynth.setNoteLength(alternationSpeed);
rt300@0 483
rt300@0 484 playingAlternating = false;
rt300@0 485 };
rt300@0 486 void setNewTestButton(Buttron * ntb){
rt300@0 487 newTestButton = ntb;
rt300@0 488 };
rt300@0 489 void set3Dbox(Leap3DBoxGL* box){
rt300@0 490 box3D = box;
rt300@0 491 };
rt300@0 492 void setBottomPanel(ButtonPanel * ntb){
rt300@0 493 bottomPanel = ntb;
rt300@0 494 };
rt300@0 495 void setControlPanel(SliderPanel* p){
rt300@0 496 panel = p;
rt300@0 497
rt300@0 498 };
rt300@0 499 void setCountdownPanel(CountdownText* cd){
rt300@0 500 countdownPanel = cd;
rt300@0 501 };
rt300@0 502 void setTargetSymbol(TargetSymbol* ts){
rt300@0 503 targetSymbol = ts;
rt300@0 504 };
rt300@0 505 void setScorePanel(TextPanel* tp){
rt300@0 506 scorePanel = tp;
rt300@0 507 };
rt300@0 508 void setFinishPanel(TextPanel* fp){
rt300@0 509 finishPanel = fp;
rt300@0 510 }
rt300@0 511 void setTargetButton(Buttron* tb){
rt300@0 512 targetPlayButton = tb;
rt300@0 513 }
rt300@0 514 int getScore(){
rt300@0 515 return testController->getScoreRunningTotal();
rt300@0 516 };
rt300@0 517
rt300@0 518 pair<int,int> getTime(){
rt300@0 519 TimerMillisec tms = timeController.getStopwatchElapsedTime();
rt300@0 520 int s = int(tms/1000);
rt300@0 521 int hs = int((tms%1000)/10);
rt300@0 522 pair<int,int> p(s,hs);
rt300@0 523 return p;
rt300@0 524 };
rt300@0 525 void countdownToNewTest(){
rt300@0 526
rt300@0 527 panel->hide();
rt300@0 528 panel->setActive(false);
rt300@0 529 scorePanel->hide();
rt300@0 530 bottomPanel->hide();
rt300@0 531 newTestButton->hide();
rt300@0 532
rt300@0 533 // set up stuff
rt300@0 534 setupNewTest();
rt300@0 535 eventLogger.logEvent(COUNTDOWN_INITIATED);
rt300@0 536
rt300@0 537 countdownPanel->showAndStart(3);
rt300@0 538
rt300@0 539 timeController.scheduleEvent(boost::bind(&MessageOrganiser::startNewTest, this), 3000);
rt300@0 540
rt300@0 541 };
rt300@0 542 void sendToGUI(vector<int> paramsToMap){
rt300@0 543 // look up these ids in mapping table
rt300@0 544 };
rt300@0 545 void saveGoodTest(Test t){
rt300@0 546
rt300@0 547 };
rt300@0 548 void playTargetButtonPressed(){
rt300@0 549
rt300@0 550 static int numPlays = 3;
rt300@0 551
rt300@0 552 Test* t = testController->getCurrentTestPtr();
rt300@0 553 if (!t->checkTargetPlaysRemaining()){
rt300@0 554 cout << t->getTargetPlaysLeft() << endl;
rt300@0 555
rt300@0 556 sendSynthValuesAgain();
rt300@0 557 targetSynth.trigger();
rt300@0 558 eventLogger.logEvent(TARGET_PLAYED);
rt300@0 559 targetPlayButton->hide();
rt300@0 560 return;
rt300@0 561
rt300@0 562 }
rt300@0 563 cout << t->getTargetPlaysLeft() << endl;
rt300@0 564
rt300@0 565 sendSynthValuesAgain();
rt300@0 566 targetSynth.trigger();
rt300@0 567 eventLogger.logEvent(TARGET_PLAYED);
rt300@0 568
rt300@0 569 return;
rt300@0 570 }
rt300@0 571 void playCandidateButtonPressed(){
rt300@0 572 //
rt300@0 573 }
rt300@0 574 void buttonPressCallback(int mappingID, int value){
rt300@0 575 if(mappingID == VOLUME_CHANGE_ID){
rt300@0 576 targetSynth.sendVolume(value);
rt300@0 577 candidateSynth.sendVolume(value);
rt300@0 578
rt300@0 579 }
rt300@0 580 if(mappingID == SPEED_CHANGE_ID){
rt300@0 581 alternationSpeed = 2*(140 - value);
rt300@0 582 vector<int> eData;
rt300@0 583 eData.push_back(alternationSpeed);
rt300@0 584 eventLogger.logEvent(SPEED_CHANGED, eData);
rt300@0 585 }
rt300@0 586 if(mappingID == NEW_TEST_ID){
rt300@0 587 countdownToNewTest();
rt300@0 588 return;
rt300@0 589 }
rt300@0 590 if (mappingID == START_ALTERNATE_ID){
rt300@0 591 if(!playingAlternating){
rt300@0 592 startAlternatingPlayback();
rt300@0 593
rt300@0 594 }else{
rt300@0 595 stopAlternatingPlayback();
rt300@0 596 }
rt300@0 597 return;
rt300@0 598 }
rt300@0 599 if(mappingID == GOOD_TEST_ID){
rt300@0 600 Test t = testController->getCurrentTest();
rt300@0 601 saveGoodTest(t);
rt300@0 602 }
rt300@0 603 if (mappingID == RANDOMISE_TARGET_ID){ // bleyeueurrrr
rt300@0 604 targetSynth.randomiseParams();
rt300@0 605 return;
rt300@0 606 }
rt300@0 607 if (mappingID == TRIGGER_TARGET_ID){
rt300@0 608 playTargetButtonPressed();
rt300@0 609
rt300@0 610 }
rt300@0 611 if (mappingID == TRIGGER_CANDIDATE_ID){
rt300@0 612 // log event
rt300@0 613 sendSynthValuesAgain();
rt300@0 614 candidateSynth.trigger();
rt300@0 615 eventLogger.logEvent(CANDIDATE_PLAYED);
rt300@0 616 // flash panel?
rt300@0 617 panel->flash();
rt300@0 618 return;
rt300@0 619 }
rt300@0 620 if (mappingID == SUBMIT_CANDIDATE){
rt300@0 621 // log event
rt300@0 622 submitPressed();
rt300@0 623
rt300@0 624 return;
rt300@0 625 }
rt300@0 626 if (mappingID == CRAP_TEST_ID){
rt300@0 627 // this is rubbish! send a log of target values, and mapping ids
rt300@0 628 vector<int> data;
rt300@0 629 vector<int> tvals = targetSynth.getAllParamValues();
rt300@0 630 vector<int> pidx = testController->getCurrentChangeableParams();
rt300@0 631 data.insert(data.end(), tvals.begin(), tvals.end());
rt300@0 632 data.insert(data.end(), pidx.begin(), pidx.end());
rt300@0 633
rt300@0 634 eventLogger.logEvent(CRAP_TEST, data);
rt300@0 635 }
rt300@0 636 if(mappingID == SHOW_HIDE_PANEL){
rt300@0 637 static bool showing;
rt300@0 638
rt300@0 639 if(showing){
rt300@0 640 cout << " showing"<<endl;
rt300@0 641
rt300@0 642 panel->show();
rt300@0 643
rt300@0 644 }else{
rt300@0 645 cout << " hiding"<<endl;
rt300@0 646 panel->hide();
rt300@0 647 }
rt300@0 648 showing = !showing;
rt300@0 649 }
rt300@0 650 if(mappingID == SHOW_HIDE_HINT){
rt300@0 651 static bool showingHint;
rt300@0 652 if(showingHint){
rt300@0 653 panel->showHint(false);
rt300@0 654 showingHint = false;
rt300@0 655 }else{
rt300@0 656 panel->showHint(true);
rt300@0 657 showingHint = true;
rt300@0 658 }
rt300@0 659 }
rt300@4 660 if(mappingID == SAVE_PRESET_HIT){
rt300@6 661 expPresetManager.savePreset("blah", candidateSynth.getAllParamValues());
rt300@4 662
rt300@4 663 }
rt300@4 664 if(mappingID == RECALL_PRESET_HIT){
rt300@4 665
rt300@4 666 loadPreset("blah");
rt300@6 667 //candidateSynth.startMetronome();
rt300@4 668
rt300@4 669 }
rt300@4 670 }
rt300@4 671 void loadPreset(string pname){
rt300@4 672
rt300@6 673 vector<int> values = expPresetManager.recallPreset(pname);
rt300@5 674 if (values.size()){
rt300@4 675 candidateSynth.setAllParams(values);
rt300@4 676 setAllSlidersToValues(values);
rt300@5 677 }else{
rt300@5 678 cout << "ERROR, no preset found" << endl;
rt300@5 679 }
rt300@0 680 }
rt300@0 681 // called from UI
rt300@0 682 void paramChangeCallback(int mappingID, int value){
rt300@0 683 candidateSynth.paramChangeCallback(mappingID, value);
rt300@0 684 vector<int> evtData;
rt300@0 685 evtData.push_back(mappingID); // or just index?
rt300@0 686 evtData.push_back(value);
rt300@0 687
rt300@0 688 eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData);
rt300@0 689 };
rt300@0 690
rt300@0 691 // could template for ui element type??
rt300@0 692 void mapButtonToAction(UIElement* control, int mappingID){
rt300@0 693 UICallbackFunction callbackF;
rt300@0 694 callbackF = boost::bind(&MessageOrganiser::buttonPressCallback, this, _1,_2);
rt300@0 695 control->addHandler(callbackF, mappingID);
rt300@0 696 currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
rt300@0 697 }
rt300@0 698
rt300@0 699
rt300@0 700 void midiFromLeap(int ctl_num, int ctl_val){
rt300@0 701
rt300@0 702
rt300@0 703 if (!okToGetLeapMidi){
rt300@0 704 return;
rt300@0 705 }
rt300@2 706
rt300@0 707
rt300@0 708 Test *theTest = testController->getCurrentTestPtr();
rt300@0 709 if (theTest == NULL) return;
rt300@0 710
rt300@2 711
rt300@0 712
rt300@0 713
rt300@2 714
rt300@0 715 vector<int> ci = theTest->getChangeableIndices();
rt300@0 716 vector<int> mids = candidateSynth.getMappingIDForIndices(ci);
rt300@0 717 if (ctl_num >= mids.size() || ctl_num < 0) return;
rt300@0 718
rt300@0 719 candidateSynth.paramChangeCallback(mids[ctl_num], ctl_val);
rt300@0 720
rt300@3 721 setUIToParam(ctl_num, ctl_val);
rt300@2 722
rt300@0 723 vector<int> evtData;
rt300@0 724 evtData.push_back(mids[ctl_num]); // or just index?
rt300@0 725 evtData.push_back(ctl_val);
rt300@0 726
rt300@0 727 eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData);
rt300@0 728 // also call UI object
rt300@0 729 // get mapping ID for
rt300@0 730 // setUIToParam(ctl_num, ctl_val);
rt300@0 731 }
rt300@3 732 // void setSlidersFromLeap(int i, int val){
rt300@3 733 // ButtronSlider* theSlider = (ButtronSlider*)panel->getSlider(i);
rt300@3 734 // theSlider->setValueAndScale(val);
rt300@3 735 // }
rt300@3 736
rt300@3 737
rt300@3 738
rt300@3 739 void setSlidersToTarget(){
rt300@3 740 // this will actually show sliders with target vals - for "memorisation" purposes mwa heh heh
rt300@3 741 // get target values
rt300@3 742 // set ui
rt300@3 743 vector<int> vals = targetSynth.getAllParamValues();
rt300@3 744 for(int i=1; i < vals.size(); i++){
rt300@3 745 setUIToParam(i, vals[i]);
rt300@3 746 }
rt300@2 747 }
rt300@0 748
rt300@0 749 };
rt300@0 750