Mercurial > hg > soniczoomios
changeset 3:43df75088d85
fixed sticking scroll
more file fiddling
author | Robert Tubb <rt300@eecs.qmul.ac.uk> |
---|---|
date | Mon, 03 Dec 2012 18:29:07 +0000 |
parents | fcb512cef986 |
children | 7541aeaebcdc |
files | 2dvector.h 2dvector.mm eventLogger.mm grid.h presetManager.h presetManager.mm testApp.h testApp.mm |
diffstat | 8 files changed, 428 insertions(+), 87 deletions(-) [+] |
line wrap: on
line diff
--- a/2dvector.h Tue Nov 27 15:34:51 2012 +0000 +++ b/2dvector.h Mon Dec 03 18:29:07 2012 +0000 @@ -8,6 +8,7 @@ */ #ifndef _2DVECTORH #define _2DVECTORH +#include <iostream> class TwoVector{ public: @@ -23,13 +24,52 @@ TwoVector operator+(TwoVector otherPoint); TwoVector operator*(TwoVector otherPoint); - TwoVector operator*(double scalar); // scalar is right operand + TwoVector operator*(const double& scalar); // scalar is right operand + + //TwoVector operator=(TwoVector otherPoint); + - //TwoVector operator=(TwoVector otherPoint); - + + double distanceTo(TwoVector otherPoint); + }; +using namespace std; +// output text formatting: (x,y) in super precise output +inline ostream& operator<<(ostream& ostr, const TwoVector& tvec){ + ostr.setf(ios_base::fixed,ios_base::floatfield); + ostr << "(" << tvec.x << "," << tvec.y << ")"; + return ostr; +} +inline istream& operator>>(istream& istr, TwoVector& tvec){ + // um + char l_paren , comma, r_paren; + + + if(istr.bad()){ + cout << "BAD INPUT"; + return istr; + } + istr.setf(ios_base::fixed,ios_base::floatfield); + + istr >> l_paren; + if(l_paren != '('){ + cout << "BAD INPUT"; + return istr; + } + istr >> tvec.x; + if(comma != ','){ + cout << "BAD INPUTa"; + return istr; + } + istr >> tvec.y; + if(r_paren != ')'){ + cout << "BAD INPUT"; + return istr; + } + return istr; +} #endif // #ifndef _2DVECTORH \ No newline at end of file
--- a/2dvector.mm Tue Nov 27 15:34:51 2012 +0000 +++ b/2dvector.mm Mon Dec 03 18:29:07 2012 +0000 @@ -8,7 +8,7 @@ */ #include "2dvector.h" -#include <iostream> + TwoVector::TwoVector(){ x = 0.0; @@ -53,7 +53,7 @@ return diff; } -TwoVector TwoVector::operator*(double scalar){ // if multiplying two vectors - elementwise +TwoVector TwoVector::operator*(const double& scalar){ TwoVector diff; diff.setCoord(x * scalar, y * scalar); return diff; @@ -64,6 +64,7 @@ diff.setCoord(otherPoint.x + x, otherPoint.y + y); return diff; } + /* TwoVector TwoVector::operator=(TwoVector otherPoint){ TwoVector result;
--- a/eventLogger.mm Tue Nov 27 15:34:51 2012 +0000 +++ b/eventLogger.mm Mon Dec 03 18:29:07 2012 +0000 @@ -27,7 +27,7 @@ } void EventLogger::logEvent(int evtType, TwoVector centre, double scale = 0.0){ - cout << "log: " << evtType << "\n"; + //cout << "log: " << evtType << "\n"; // scroll has 2 double coords // zoom has 1 double scale @@ -44,6 +44,7 @@ // save preset }else if(evtType == -1){ // save preset + cout << "move:\t" << centre << "\n"; }else{ // slider change }
--- a/grid.h Tue Nov 27 15:34:51 2012 +0000 +++ b/grid.h Mon Dec 03 18:29:07 2012 +0000 @@ -11,14 +11,21 @@ #include <iostream> #include "2dvector.h" +#include "ofMain.h" +#include "eventLogger.h" +#include "presetManager.h" using namespace std; class Grid { private: double scale; // surface units per pixel - double maxValue; // width of entire space - double minValue; // smallest zoom + const double maxValue; // width of entire space + const double minValue; // smallest zoom + const int paramsPerDim; // no of parameters per dimension ( + int codeLength; // the 1d size of the code, determines max extent of single tile, related to params per dim + const int paramBitDepth; // number of bits for the parameter control data - i.e. always 7 for midi CC + TwoVector topLeft; // top left corner of view, surface coords TwoVector bottomRight; TwoVector size; // size of view, surface coords @@ -26,9 +33,7 @@ TwoVector centre; bool maxZoom, minZoom; int cubeWidth; // side of hypercube. 2 for binary coding. - int paramsPerDim; // no of parameters per dimension ( - int codeLength; // the 1d size of the code, determines max extent of single tile, related to params per dim - int paramBitDepth; // number of bits for the parameter control data - i.e. always 7 for midi CC + vector< vector<bool> > vcode; // vector<int> icode; vector<int> transSeq; @@ -41,38 +46,45 @@ void viewWasChanged(); void checkConsistencies(); - vector<int> calculateParamsFromCoord(TwoVector coord); - TwoVector calculateCoordFromParams(vector<int> params); + - vector<bool> intToGray(int num, int dimToTravel=3); - vector<int> coordTobase32(double coord); - vector<int> grayToMidi(vector<vector <bool> > grayCodes); + vector<bool> intToGray(int num, int dimToTravel=3) const; + vector<int> coordTobase32(double coord) const; + vector<int> grayToMidi(vector<vector <bool> > grayCodes) const; // the inverse stuff - int grayToInt(vector<bool>); - double base32toCoord(vector<int>); - vector<vector <bool> > midiToGray(vector<int>); - vector<int> codesToBase32(vector<vector<bool> >); + int grayToInt(vector<bool>) const; + double base32toCoord(vector<int>) const; + vector<vector <bool> > midiToGray(vector<int>) const; + vector<int> codesToBase32(vector<vector<bool> >) const; vector<int> walkDiff(vector<bool> left, vector<bool> right); // not used... not worth it! void displayInfo(); + void drawPresets(); void setCoord(TwoVector coord); + TwoVector coordToPixel(TwoVector coord); public: Grid(); ~Grid(); void init(); - void move(int moveX, int moveY); // shift view by pixels + void move(TwoVector moveP); // shift view by pixels void zoom(float factor); void draw(); // draw lines + void update(); // change according to zoom + vector<int> calculateParamsFromCoord(TwoVector coord) const; + TwoVector calculateCoordFromParams(vector<int> params) const; + vector<int> getParams(); TwoVector getCoord(); // the inverse stuff void setParams(vector<int>); + + };
--- a/presetManager.h Tue Nov 27 15:34:51 2012 +0000 +++ b/presetManager.h Mon Dec 03 18:29:07 2012 +0000 @@ -14,26 +14,52 @@ #include "ofxiPhone.h" #include "ofxiPhoneExtras.h" #include "2dvector.h" +#include "grid.h" + //--------------------------------------------------------------------------- class Preset{ +public: -public: int presetID; string name; TwoVector coordinates; + Preset(TwoVector acoord, string aname,int aID){ coordinates = acoord; name = aname; presetID = aID; + + }; + Preset(int aID){ + coordinates.setCoord(0.0,0.0); + name = "Blank"; + presetID = aID; }; + }; + + +//--------------------------------------------------------------------------- +inline ostream& operator<<(ostream & os, const Preset& p) +{ + os << "Name:" << p.name << "|"; + os << "Coord:" << p.coordinates << "\n"; + + return(os); +} +//--------------------------------------------------------------------------- +inline istream& operator>>(istream & is, Preset& p) +{ + //um + return(is); +} //--------------------------------------------------------------------------- class PresetManager{ public: int nextID; - + int timesOpened; // names values // check if already there // find and return all(?) presets within a certain coordinate range
--- a/presetManager.mm Tue Nov 27 15:34:51 2012 +0000 +++ b/presetManager.mm Mon Dec 03 18:29:07 2012 +0000 @@ -9,18 +9,24 @@ #include "presetManager.h" //--------------------------------------------------------------------------- - +extern Grid theGridView; PresetManager presetManager; //--------------------------------------------------------------------------- PresetManager::PresetManager(){ + timesOpened = 0; + startupLoadAll(); + + nextID = 0; } //--------------------------------------------------------------------------- -int PresetManager::addPreset(TwoVector coord, string name){ +int PresetManager::addPreset(const TwoVector coord, const string name){ + + // check for same name vector<Preset *>::iterator iter; for(iter = thePresets.begin(); iter < thePresets.end(); iter++){ @@ -36,6 +42,8 @@ return -2; } + + // check for same coords (!?!) thePresets.push_back(new Preset(coord, name,nextID)); @@ -43,18 +51,61 @@ return nextID++; } //--------------------------------------------------------------------------- -vector<TwoVector > getPresetsInRange(TwoVector min, TwoVector max){ +vector<TwoVector > PresetManager::getPresetsInRange(const TwoVector min, const TwoVector max){ //return all the coordinates. oh and names (displayed at certain scales?). -} -//--------------------------------------------------------------------------- -void startupLoadAll(){ - // get stuff from XML -} -//--------------------------------------------------------------------------- -void exitAndSaveAll(){ + + // TODO INEFFICIENT FOR LOTS OF PRESETS. CALLED EVERY GRAPHICS UPDATE! + // so: put burden on saving rather than retrieving, make into list and index using coordinates + + vector<TwoVector > results; + vector<Preset *>::iterator presetIter; + for(presetIter = thePresets.begin(); presetIter < thePresets.end(); presetIter++){ + if( ((*presetIter)->coordinates.x > min.x ) && ((*presetIter)->coordinates.y > min.y ) && ((*presetIter)->coordinates.x < max.x ) && ((*presetIter)->coordinates.y < max.y )){ + results.push_back((*presetIter)->coordinates); + } + + } + return results; } //--------------------------------------------------------------------------- +void PresetManager::startupLoadAll(){ + // get stuff from file + // load file + + string fname = ofxiPhoneGetDocumentsDirectory() + "presets.dat"; + char *fileName = (char*)fname.c_str(); + ifstream from(fileName); + string line; + + // simply prints file + while(from >> line){ + cout << line << "\n"; + + } + + + + timesOpened++; +} +//--------------------------------------------------------------------------- +void PresetManager::exitAndSaveAll(){ + ofFile presetFile(ofxiPhoneGetDocumentsDirectory() +"presets.dat",ofFile::WriteOnly); + + cout << "Exit and save presets\n"; + vector<Preset *>::iterator presetIter; + + for(presetIter = thePresets.begin(); presetIter < thePresets.end(); presetIter++){ + //vector<int> params; + //params = theGridView.calculateParamsFromCoord((*presetIter)->coordinates); + presetFile << **presetIter << "\n"; + cout << **presetIter << "\n"; + + } + presetFile.close(); + +} +//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //---------------------------------------------------------------------------
--- a/testApp.h Tue Nov 27 15:34:51 2012 +0000 +++ b/testApp.h Mon Dec 03 18:29:07 2012 +0000 @@ -10,14 +10,20 @@ #include "eventLogger.h" #include "AppCore.h" +#include "presetManager.h" +#include "eventLogger.h" +#include "ofxPd.h" +#include "frequencer.h" + #define HOST "169.254.1.1" #define PORT 12345 class testApp : public ofxiPhoneApp { - public: + +public: - + int prevTouchX; int prevTouchY; double prevDist; @@ -40,6 +46,7 @@ TwoVector prevMove, prevMove2; vector<int> sliderVals; + vector<int> freqIndexes; int numActiveTouches; @@ -80,8 +87,15 @@ void zoomGUIEvent(ofxUIEventArgs &e); void setupZoomGui(); - void updateSliderValue(int which, float value); - void setGUISliders(vector<int> vals); + void sliderMoved(int which, float value); + void setAllGUISliders(vector<int> vals); + void sendParametersToPD(); + void sendOscShape(int ctrlin); + void sendFiltShape(int ctrlin); + void sendFiltType(int ctrlin); + void sendFiltFreq(int ctrlin); + void sendEnvShape(int ctrlin); + void sendModFreq(int ctrlin); ofxUICanvas *zoomGUI;
--- a/testApp.mm Tue Nov 27 15:34:51 2012 +0000 +++ b/testApp.mm Mon Dec 03 18:29:07 2012 +0000 @@ -1,13 +1,11 @@ #include "testApp.h" -#include "grid.h" -#include "presetManager.h" -#include "eventLogger.h" -#include "ofxPd.h" extern Grid theGridView; extern PresetManager presetManager; extern EventLogger eventLogger; +extern Frequencer frequencer; + //-------------------------------------------------------------- void testApp::setup(){ ofSetOrientation(OF_ORIENTATION_90_LEFT); @@ -17,7 +15,7 @@ // open an outgoing connection to HOST:PORT sender.setup( HOST, PORT ); - ofSetFrameRate(40); + ofSetFrameRate(30); // reciever @@ -28,15 +26,25 @@ yLocked = false; numActiveTouches = 0; - touch0.setCoord(1,2); + touch0.setCoord(17./7., 2./3.); touch1.setCoord(10,20); + + TwoVector ttest; + string str = "(4.5,7.8)"; + stringstream sstr; + sstr << str; + sstr >> ttest; + cout << "ttest: " << ttest.x << "\n"; + + prevTouch0.setCoord(1,2); prevTouch1.setCoord(10,20); prevDist = 10; theGridView.init(); - slowFactor = 0.97; + slowFactor = 0.98; + setupStandardGui(); standardGUIShowing = false; @@ -50,6 +58,13 @@ sliderVals.push_back(64); } + // the 5 harmonics for the frequencer + freqIndexes.push_back(0); + freqIndexes.push_back(4); + freqIndexes.push_back(6); + freqIndexes.push_back(7); + freqIndexes.push_back(8); + keyboard = new ofxiPhoneKeyboard(500,380,320,32); keyboard->setVisible(false); keyboard->setBgColor(255, 255, 255, 255); @@ -70,18 +85,22 @@ ofSoundStreamSetup(2, 1, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 3); } +#pragma mark GUI //-------------------------------------------------------------- void testApp::setupZoomGui(){ - zoomGUI = new ofxUICanvas(ofGetWidth()-200,0,190,125); + zoomGUI = new ofxUICanvas(ofGetWidth()-200,0,190,300); zoomGUI->setTheme(OFX_UI_THEME_HACKER ); - ofxUIWidget *bwidge = zoomGUI->addLabelToggle("SWITCH VIEW", false); + zoomGUI->addLabelToggle("SWITCH VIEW", false); zoomGUI->addLabelButton("SAVE PRESET", false); zoomGUI->addLabelToggle("LOCK SEQUENCE (X)", false); zoomGUI->addLabelToggle("LOCK SYNTH (Y)", false); + zoomGUI->addLabelButton("ZOOM MIN", false); + zoomGUI->addLabelButton("ZOOM MAX", false); + ofAddListener(zoomGUI->newGUIEvent, this, &testApp::zoomGUIEvent); } //-------------------------------------------------------------- @@ -96,38 +115,58 @@ if(standardGUIShowing){ // set the slider values to stuff got from zoomer sliderVals = theGridView.getParams(); - setGUISliders(sliderVals); + setAllGUISliders(sliderVals); } }else if(e.widget->getName() == "SAVE PRESET") { - cout << "SAVE PRESET\n"; - // uh... - // TwoVector preset = theGridView.getCoord(); - // presetManager.savePreset(preset); - // just coordinate or all the dims? - TwoVector preset = theGridView.getCoord(); + if(((ofxUIButton *)e.widget)->getValue()){ + cout << "SAVE PRESET\n"; + stringstream n; + double timemsd = [NSDate timeIntervalSinceReferenceDate]; + long long timems = (long long)(timemsd*1000); + n << "P" << timems; + string name = n.str(); + + presetManager.addPreset(theGridView.getCoord(),name); + } + /* if(!keyboard->isKeyboardShowing()){ keyboard->openKeyboard(); keyboard->setVisible(true); } else{ keyboard->setVisible(false); } + */ // set some kind of modal dialog thing to stop other stuff going on... // this wont work - presetManager.addPreset(preset,keyboard->getText()); + // HACK just name it after time + }else if(e.widget->getName() == "LOCK SEQUENCE (X)") { - cout << "LOCK SEQUENCE (X)\n"; - // lock - xLocked = !xLocked; + + cout << "LOCK SEQUENCE (X)\n"; + // lock + xLocked = !xLocked; + }else if(e.widget->getName() == "LOCK SYNTH (Y)") { + cout << "LOCK SYNTH (Y)\n"; // lock yLocked = !yLocked; + }else if(e.widget->getName() == "ZOOM MIN") + { + if(((ofxUIButton *)e.widget)->getValue()){ + cout << "ZOOM MIN\n"; + } + }else if(e.widget->getName() == "ZOOM MAX") + { + if(((ofxUIButton *)e.widget)->getValue()){ + cout << "ZOOM MAX\n"; + } }else{ cout << "GUI error : unknown event recieved\n"; } @@ -184,7 +223,7 @@ { //cout << "param change: " << p; ofxUISlider *slider = (ofxUISlider *) e.widget; - updateSliderValue(i-1,slider->getScaledValue()); // internal array 0 indexed + sliderMoved(i-1,slider->getScaledValue()); // internal array 0 indexed } } @@ -193,23 +232,62 @@ } //-------------------------------------------------------------- -void testApp::updateSliderValue(int which, float value){ +void testApp::sliderMoved(int which, float value){ + // an update caused by slider view being touched sliderVals[which] = (int)value; theGridView.setParams(sliderVals); + + // TODO if <5 do frequencer stuff and send list to PD + // if > 5 send control value to PD + sendParametersToPD(); } //-------------------------------------------------------------- -void testApp::setGUISliders(vector<int> vals){ +void testApp::setAllGUISliders(vector<int> vals){ + // an update caused by zoomer view being moved for(int i = 0; i<10;i++){ sliders[i]->setValue(vals[i]); sliderVals[i] = vals[i]; } + } //-------------------------------------------------------------- +void testApp::sendParametersToPD(){ + // frequencer stuff to get 16 steps + vector<double> vals; + + + vals.push_back((sliderVals[0]+32)*8.); // DC offset + for(int i=1; i<5;i++){ + vals.push_back((sliderVals[i] - 64)*2.); + } + + vector<double> steps = frequencer.freqMagEdit(freqIndexes, vals); + // send a list using the List object + List seqSteps; + + seqSteps.addSymbol("seqSteps"); + for(int i=0; i < 16; i++){ + seqSteps.addFloat(round(steps[i])); // rounding here?? + } + + core.pd.sendList("fromOF", seqSteps); + //core.pd.sendMessage("fromOF", "msg", seqSteps); + + // implement synth param calculations here? + // oscshape, filt type , cut off, envelope, mod freq (fm for sine, ? for pulse, sync for saw) + // oscillators: + sendOscShape(sliderVals[5]); + sendFiltType(sliderVals[6]); + sendFiltFreq(sliderVals[7]); + sendEnvShape(sliderVals[8]); + sendModFreq(sliderVals[9]); + +} +#pragma mark STANDARD OF FUNCTIONS +//-------------------------------------------------------------- void testApp::update(){ //we do a heartbeat on iOS as the phone will shut down the network connection to save power //this keeps the network alive as it thinks it is being used. - - if( ofGetFrameNum() % 120 == 0 ){ ofxOscMessage m; m.setAddress( "/misc/heartbeat" ); @@ -218,23 +296,32 @@ } // continiue to move at velocity - if (numActiveTouches == 0 && moveVel.norm() > 0.01){ - theGridView.move(moveVel.x,moveVel.y); - moveVel = moveVel*slowFactor; + + if (numActiveTouches == 0){ // no touches, use momentum + // TODO set velocity to 0 when hits walls + + if(moveVel.norm() > 0.1){ + theGridView.move(moveVel); + moveVel = moveVel*slowFactor; + + // and get new parameter values + if(standardGUIShowing)setAllGUISliders(theGridView.getParams()); + sendParametersToPD(); + }else if(moveVel.norm() > 0.01){ + // stop it + moveVel.setCoord(0.0,0.0); + if(standardGUIShowing)setAllGUISliders(theGridView.getParams()); + sendParametersToPD(); + }else{ + // stopped - do nothing + } + } // continiue to zoom at velocity if (numActiveTouches < 2 && abs(zoomVel)>0.001){ theGridView.zoom(zoomVel + 1.0); // +1 because zoomVel factor is + or - , wheras zoom is a multiplier near 1 zoomVel = zoomVel*slowFactor; } - - // we need this? - theGridView.update(); - vector<int> params = theGridView.getParams(); // FILTER HERE? NEED FLOATS... - setGUISliders(params); - - // sendOSCParams(); - // sendMIDIParams(); } //-------------------------------------------------------------- void testApp::sendOSCParams(){ @@ -268,6 +355,7 @@ //-------------------------------------------------------------- void testApp::exit(){ core.exit(); + presetManager.exitAndSaveAll(); delete standardGUI; delete zoomGUI; } @@ -313,7 +401,7 @@ if(standardGUIShowing){ - // check if in GUI area + // TODO check if in GUI area if(touch.x < 256) return; } @@ -345,7 +433,12 @@ prevMove2 = prevMove; prevMove = move; - theGridView.move(move.x,move.y); + theGridView.move(move); + + // and get new parameter values + setAllGUISliders(theGridView.getParams()); + sendParametersToPD(); + } //-------------------------------------------------------------- void testApp::handleZoom(){ @@ -366,9 +459,7 @@ theGridView.zoom(zoomFactor); prevDist = dist; - // TODO: when num touches goes down to 1 after zoom prevTouch can be hugely different! - // also if try to move with other finger after zoom , this is touch1 :( - // prevTouch0 = ??? + } //-------------------------------------------------------------- void testApp::touchUp(ofTouchEventArgs &touch){ @@ -432,6 +523,21 @@ void testApp::touchCancelled(ofTouchEventArgs& args){ } +//--------------------------------------------------------------- +// AUDIO STUFF +//--------------------------------------------------------------- + +#pragma mark AUDIO STREAMS +//-------------------------------------------------------------- +void testApp::audioReceived(float * input, int bufferSize, int nChannels) { + core.audioReceived(input, bufferSize, nChannels); +} + +void testApp::audioRequested(float * output, int bufferSize, int nChannels) { + core.audioRequested(output, bufferSize, nChannels); +} +//--------------------------------------------------------------- +#pragma mark UTILITIES // 5hz cut off const double fB[3] = {0.049489956268677, 0.098979912537354, 0.049489956268677}; @@ -469,15 +575,105 @@ return y0; } -//--------------------------------------------------------------- -// AUDIO STUFF -//--------------------------------------------------------------- -//-------------------------------------------------------------- -void testApp::audioReceived(float * input, int bufferSize, int nChannels) { - core.audioReceived(input, bufferSize, nChannels); +void testApp::sendOscShape(int ctrlin){ + + static int numpoints = 5; + static int numcontrols = 5; + //float values[points][controls] = + float ctrlout[numcontrols]; + string ctrlName[5] = {"pWidth" , "sqVol", "sawVol", "sineVol", "FMAmt"}; + float values[5][5] = + {{0.5, 0., 0., 1., 1.}, // 0 + {0.5, 0., 0., 1., 0.}, // 32 + {0.5, 0., 1., 0., 0.}, // 64 + {0.5, 1., 1., 0., 0.}, // 96 + {0.01,1., 1., 0., 0.}}; // 127 + + float fidx = (numpoints-1)*ctrlin/128.; + int idx = floor(fidx); + float frac = fidx - idx; + for(int i=0; i < numcontrols; i++){ + ctrlout[i] = (1 - frac)*values[idx][i] + (frac)*values[idx+1][i]; + // send to PD + List toPD; + + toPD.addSymbol(ctrlName[i]); + toPD.addFloat(ctrlout[i]); // rounding here?? + + core.pd.sendList("fromOF", toPD); + //cout << ctrlName[i] << "sending" << ctrlout[i] << "\n"; + } + } - -void testApp::audioRequested(float * output, int bufferSize, int nChannels) { - core.audioRequested(output, bufferSize, nChannels); +void testApp::sendFiltType(int ctrlin){ + static int numpoints = 3; + static int numcontrols = 4; + //float values[points][controls] = + float ctrlout[numcontrols]; + string ctrlName[4] = {"lpLev" , "bpLev", "hpLev", "reson"}; + float values[3][4] = + {{1., 0., 0., 1}, // 0 + {0., 10., 0., 10}, // 64 + {0., 0., 1., 1}}; // 127 + + float fidx = (numpoints-1)*ctrlin/128.; + int idx = floor(fidx); + float frac = fidx - idx; + for(int i=0; i < numcontrols; i++){ + ctrlout[i] = (1 - frac)*values[idx][i] + (frac)*values[idx+1][i]; + // send to PD + List toPD; + + toPD.addSymbol(ctrlName[i]); + toPD.addFloat(ctrlout[i]); // rounding here?? + + core.pd.sendList("fromOF", toPD); + //cout << ctrlName[i] << "sending" << ctrlout[i] << "\n"; + } } +void testApp::sendFiltFreq(int ctrlin){ + List toPD; + + toPD.addSymbol("filtFreq"); + toPD.addFloat(ctrlin); + + core.pd.sendList("fromOF", toPD); +} +void testApp::sendEnvShape(int ctrlin){ + static int numpoints = 5; + static int numcontrols = 3; + //float values[points][controls] = + float ctrlout[numcontrols]; + string ctrlName[3] = {"attack" , "decay", "sustain"}; + float values[5][3] = + {{0., 0., 0.}, // 0 + {0., 0.5, 0.}, // 32 + {0.0, 1., 0.8}, // 64 + {0.99, 0.3, 0.}, // 96 + {0.3, 0.1, 0.}}; // 127 + + float fidx = (numpoints-1)*ctrlin/128.; + int idx = floor(fidx); + float frac = fidx - idx; + for(int i=0; i < numcontrols; i++){ + ctrlout[i] = (1 - frac)*values[idx][i] + (frac)*values[idx+1][i]; + // send to PD + List toPD; + + toPD.addSymbol(ctrlName[i]); + toPD.addFloat(ctrlout[i]); // rounding here?? + + core.pd.sendList("fromOF", toPD); + //cout << ctrlName[i] << "sending" << ctrlout[i] << "\n"; + } +} +void testApp::sendModFreq(int ctrlin){ + float fm = ctrlin/127.; + List toPD; + + toPD.addSymbol("FMFreq"); + toPD.addFloat(fm); // rounding here?? + + core.pd.sendList("fromOF", toPD); +} \ No newline at end of file