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 "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@16: #include "IconPanel.h" 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@11: //typedef boost::function AppModeChangeFunction; rt300@0: rt300@0: class MessageOrganiser { rt300@8: rt300@8: public: rt300@8: void init(PDSynthWrapper& cs, PDSynthWrapper& ts){ rt300@8: candidateSynth = cs; rt300@8: targetSynth = ts; rt300@9: rt300@9: onlyChangeCandidateOnTrigger = true; rt300@8: } rt300@8: // could template for ui element type?? rt300@8: void mapButtonToAction(UIElement* control, int mappingID){ rt300@8: UICallbackFunction callbackF; rt300@8: callbackF = boost::bind(&MessageOrganiser::buttonPressCallback, this, _1,_2); rt300@8: control->addHandler(callbackF, mappingID); rt300@8: currentMapping.insert(std::pair(mappingID,control)); rt300@8: } rt300@17: rt300@17: rt300@9: void setControlPanel(SliderPanel* p){ // a bit specific?? rt300@9: panel = p; rt300@9: rt300@9: }; rt300@9: void setBottomPanel(ButtonPanel * ntb){ rt300@9: bottomPanel = ntb; rt300@9: }; rt300@16: rt300@16: rt300@16: void setIconPanel(IconPanel * ip){ rt300@16: presetIconPanel = ip; rt300@16: } rt300@16: void setInstructionPanel(TextPanel * ip){ rt300@16: instructionPanel = ip; rt300@16: instructionPanel->show(); rt300@16: } rt300@16: rt300@16: rt300@16: //----------------------------------------------------------------------------- rt300@16: void hideMyPanels(){ rt300@16: presetIconPanel->hide(); rt300@16: instructionPanel->hide(); rt300@16: bottomPanel->hide(); rt300@16: panel->hide(); rt300@16: } rt300@16: void showMyPanels(){ rt300@16: presetIconPanel->show(); rt300@16: instructionPanel->show(); rt300@16: bottomPanel->show(); rt300@16: panel->show(); rt300@16: } rt300@8: protected: rt300@8: rt300@8: PDSynthWrapper candidateSynth; rt300@0: PDSynthWrapper targetSynth; rt300@9: ButtonPanel* bottomPanel; // shows during test : play buttons and submit rt300@9: SliderPanel* panel; rt300@16: rt300@16: IconPanel* presetIconPanel; rt300@16: TextPanel* instructionPanel; rt300@16: rt300@9: map currentMapping; // could get more sophisticated if not 1-1 ? rt300@8: rt300@0: rt300@9: void triggerCandidateSound(){ rt300@9: // log event rt300@9: sendSynthValuesAgain(); rt300@9: candidateSynth.trigger(); rt300@9: eventLogger.logEvent(CANDIDATE_PLAYED); rt300@9: // flash panel? rt300@9: panel->flash(); rt300@9: } rt300@0: rt300@9: void paramChangeCallback(int mappingID, int value){ rt300@9: rt300@9: if(onlyChangeCandidateOnTrigger){ rt300@9: candidateSynth.paramChangeCallback(mappingID, value, false); rt300@9: }else{ rt300@9: candidateSynth.paramChangeCallback(mappingID, value, true); rt300@9: } rt300@0: rt300@9: vector evtData; rt300@9: evtData.push_back(mappingID); // or just index? rt300@9: evtData.push_back(value); rt300@9: rt300@9: eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData); rt300@9: }; rt300@0: rt300@0: void sendSynthValuesAgain(){ rt300@0: candidateSynth.sendAllParams(); rt300@0: targetSynth.sendAllParams(); rt300@0: }; rt300@8: 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@16: //----------------------------------------------------------------------------- rt300@16: rt300@16: void mapSlidersToParams(vector elems, vector mids){ rt300@16: rt300@16: vector::iterator elit; rt300@16: vector typeListLog; rt300@16: int i = 0; rt300@16: for(elit=elems.begin(); elitgetType() == SLIDER){ rt300@16: if(i >= mids.size()){ rt300@16: rt300@16: cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl; rt300@16: } rt300@16: rt300@16: ButtronSlider* theSlider = (ButtronSlider*)(*elit); rt300@16: mapControlToParam((*elit), mids[i]); rt300@16: theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i])); rt300@16: cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl; rt300@16: theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i]))); rt300@16: i++; rt300@16: typeListLog.push_back(int(SLIDER)); rt300@16: rt300@16: }else{ rt300@16: cout << "ERROR ERROR: ui type not handled my mapping function !" << endl; rt300@16: } rt300@16: } rt300@16: rt300@16: eventLogger.logEvent(CONTROL_LIST,typeListLog); rt300@16: }; rt300@16: 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@8: 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: rt300@8: virtual void buttonPressCallback(int mappingID, int value){ rt300@0: rt300@0: }; 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@14: void setSlidersToDefault(){ rt300@14: for(int i=1; i < targetSynth.getNumParams(); i++){ rt300@14: setUIToParam(i, 0); rt300@14: } rt300@14: } rt300@9: rt300@9: bool onlyChangeCandidateOnTrigger; rt300@0: rt300@0: }; rt300@0: