Mercurial > hg > soniczoomios
changeset 4:7541aeaebcdc
presest store locally. bit crap still though.
author | Robert Tubb <rt300@eecs.qmul.ac.uk> |
---|---|
date | Tue, 04 Dec 2012 18:36:00 +0000 |
parents | 43df75088d85 |
children | 5ee5ef99e117 |
files | 2dvector.h eventLogger.h eventLogger.mm frequencer.h frequencer.mm grid.mm presetManager.h presetManager.mm testApp.mm |
diffstat | 9 files changed, 1191 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- a/2dvector.h Mon Dec 03 18:29:07 2012 +0000 +++ b/2dvector.h Tue Dec 04 18:36:00 2012 +0000 @@ -40,6 +40,8 @@ // 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.precision(1); + ostr << "(" << tvec.x << "," << tvec.y << ")"; return ostr; } @@ -53,21 +55,23 @@ cout << "BAD INPUT"; return istr; } + istr.setf(ios_base::fixed,ios_base::floatfield); + istr.precision(1); - istr >> l_paren; + istr >> l_paren >> tvec.x >> comma >> tvec.y >> r_paren; if(l_paren != '('){ - cout << "BAD INPUT"; + cout << "BAD INPUT ("; return istr; } - istr >> tvec.x; + if(comma != ','){ - cout << "BAD INPUTa"; + cout << "BAD INPUT ,"; return istr; } - istr >> tvec.y; + if(r_paren != ')'){ - cout << "BAD INPUT"; + cout << "BAD INPUT )"; return istr; } return istr;
--- a/eventLogger.h Mon Dec 03 18:29:07 2012 +0000 +++ b/eventLogger.h Tue Dec 04 18:36:00 2012 +0000 @@ -12,30 +12,41 @@ #define __oscSenderExample__eventLogger__ +#include "ofMain.h" +#include "ofxiPhone.h" +#include "2dvector.h" +#include "ofxiPhoneExtras.h" +#include <sys/time.h> +#include <iostream> +#include <string> +#include <map> +#include "2dvector.h" +enum leventType {SAVE_PRESET, SAVE_DESET, SCROLL, ZOOM, CHANGE_SLIDER, SWAP_VIEW}; -#include <iostream> -#include "2dvector.h" -enum eventType {PRESET, DESET, SCROLL, ZOOM, SLIDER}; +class lEvent{ -class Event{ // try and make this as compact as possible. - int eventType; // -4 save deset, -3 save preset, -2 zoom, -1 scroll, 0-D slider index + leventType eventType; double val1; // x coord, scale if zoom double val2; // y coord, 0 if zoom + int sliderID; + }; + + class EventLogger{ public: // what we need... /* time, type, value */ - vector<Event> events; + vector<lEvent> theEvents; - int userID; // get something from hardware?? + string userID; // get something from hardware?? EventLogger(); - void logEvent(int evtType,TwoVector centre, double scale); + void logEvent(const leventType& evtType,const TwoVector& centre, const double& scale, const int& sliderID); void sendHttp(); };
--- a/eventLogger.mm Mon Dec 03 18:29:07 2012 +0000 +++ b/eventLogger.mm Tue Dec 04 18:36:00 2012 +0000 @@ -5,11 +5,7 @@ // Created by Robert Tubb on 05/11/2012. // // -#include "ofMain.h" -#include "ofxiPhone.h" -#include "2dvector.h" -#include "ofxiPhoneExtras.h" -#include <sys/time.h> + #include "eventLogger.h" @@ -17,16 +13,21 @@ EventLogger eventLogger; EventLogger::EventLogger(){ - - // if first time opened request a user ID from the server. use time? + + // if first time opened request a user ID from the server... use time? double timemsd = [NSDate timeIntervalSinceReferenceDate]; long long timems = (long long)(timemsd*1000); cout << "Time (ms) = " << timems << "\n"; + + + CFUUIDRef theUUID = CFUUIDCreate(NULL); + CFStringRef tstring = CFUUIDCreateString(NULL, theUUID); + CFRelease(theUUID); } -void EventLogger::logEvent(int evtType, TwoVector centre, double scale = 0.0){ +void EventLogger::logEvent(const leventType& evtType,const TwoVector& centre, const double& scale = 1.0, const int& sliderID = -1){ //cout << "log: " << evtType << "\n"; // scroll has 2 double coords @@ -35,19 +36,29 @@ // switch view has view type // slider change has int slider index and 1 int value - // store in local vector - if(evtType == -4){ - // save deset - }else if(evtType == -3){ - // save preset - }else if(evtType == -2){ - // save preset - }else if(evtType == -1){ - // save preset - cout << "move:\t" << centre << "\n"; - }else{ - // slider change + // get time for key index + + switch ( evtType ) { + case SAVE_PRESET: + // Code + break; + case SAVE_DESET: + // Code + break; + case SCROLL: + // Code + break; + case ZOOM: + // Code + break; + case CHANGE_SLIDER: + // Code + break; + default: + // Code + break; } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frequencer.h Tue Dec 04 18:36:00 2012 +0000 @@ -0,0 +1,42 @@ +// +// frequencer.h +// oscSenderExample +// +// Created by Robert Tubb on 27/11/2012. +// +// This is a C++ version of freqMaster.js max script + +#ifndef __oscSenderExample__frequencer__ +#define __oscSenderExample__frequencer__ + +#include <iostream> +#include "ofMain.h" +#include "math.h" + + +class Frequencer{ + +private: + vector<double> timePoints; + vector<double> freqMag; + vector<double> freqPhase; + int N; + + + void dft(); + void idft(); +public: + Frequencer(); + void clear(); + void timeEdit(int n, double value); + void timeEdit(vector<double> allValues); + void freqMagEdit(int k, double mag); + vector<double> freqMagEdit(vector<int> indexes, vector<double> values); + void freqPhaseEdit(int k, double phase); + vector<double> freqPhaseEdit(vector<int> indexes, vector<double> values); + + double getPoint(int idx); + //int getPoint(int idx); // rounded +}; + +#endif /* defined(__oscSenderExample__frequencer__) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frequencer.mm Tue Dec 04 18:36:00 2012 +0000 @@ -0,0 +1,167 @@ +// +// frequencer.cpp +// oscSenderExample +// +// Created by Robert Tubb on 27/11/2012. +// +// + +#include "frequencer.h" +Frequencer frequencer; + +Frequencer::Frequencer(){ + + N = 16; + + for(int i = 0; i<N;i++){ + timePoints.push_back(0.0); + freqMag.push_back(0.0); + freqPhase.push_back(0.0); + } + +} +///////////////////////////////////////////////////// +///////////////////////////////////////////////////// + +void Frequencer::timeEdit(int n, double value){ + + // update internal + timePoints[n] = value; + + // calculate transform + dft(); + + //TODO output freq domain - to PD + +} + +void Frequencer::timeEdit(vector<double> allValues){ + + // update internal + vector<double>::iterator iter; + vector<double>::iterator iter2; + iter = allValues.begin(); + iter2 = timePoints.begin(); + for (iter = allValues.begin(); iter < allValues.end(); iter++,iter2++){ + *iter = *iter2; + } + + + // calculate transform + dft(); + + //TODO output freq domain - to PD + +} + +///////////////////////////////////////////////////// +///////////////////////////////////////////////////// + +void Frequencer::freqMagEdit(int k, double mag){ + // put into local store, + + freqMag[k] = mag; + + // making sure to conjugate + + freqMag[N-k] = freqMag[k]; + + + // calculate transform + idft(); + + + //TODO output time domain + + +} + +vector<double> Frequencer::freqMagEdit(vector<int> indexes, vector<double> values){ + if(indexes.size() != values.size()){ + cout << "freqMagEdit error: indexes dont match values\n"; + return timePoints; + } + // put into local store, + for(int i=0;i<indexes.size();i++){ + freqMag[indexes[i]] = values[i]; + freqMag[N-indexes[i]] = freqMag[indexes[i]]; + } + + // calculate transform + idft(); + + return timePoints; +} + + +///////////////////////////////////////////////////// +///////////////////////////////////////////////////// + +void Frequencer::freqPhaseEdit(int k, double phase){ + N = 16; + // put into local store + freqPhase[k] = phase; + + // making sure to conjugate + + freqPhase[N-k] = - freqPhase[k]; + + // calculate transform + idft(); + // TODO output time domain + +} + +///////////////////////////////////////////////////// +///////////////////////////////////////////////////// + +void Frequencer::dft(){ + + // we have 16 time points. work out freqs and phases + int n = 0; + int k = 0; + double xre = 0.; + double xim = 0.; + + for(k=0; k < N; k++){ + // work out xn + xre = 0.; + xim = 0.; + for(n=0;n < N;n++){ + xre = xre + timePoints[n]*cos( (2.*PI/(float)N)*n*k); + xim = xim + timePoints[n]*sin( (2.*PI/(float)N)*n*k); + + } + freqMag[k] = sqrt(pow(xre,2) + pow(xim,2.)); // MAGNITUDE + freqPhase[k] = -atan2(xim,xre); + } + +} + + + +///////////////////////////////////////////////////// +///////////////////////////////////////////////////// + +void Frequencer::idft(){ + + // we have some freqs and phases. work out real time points (conj) + int n = 0; + int k = 0; + double xre = 0.; + double xim = 0.; + + for(n=0; n < N; n++){ + // work out xn + xre = 0.; + xim = 0.; + for(k=0;k < N;k++){ + xre = xre + freqMag[k]*cos( (2.*PI/(float)N)*n*k + freqPhase[k]); + + } + timePoints[n] = xre/(float)N; // divided by N ??? + } + +} +///////////////////////////////////////////////////// +///////////////////////////////////////////////////// \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/grid.mm Tue Dec 04 18:36:00 2012 +0000 @@ -0,0 +1,826 @@ +// +// grid.cpp +// oscSenderExample +// +// Created by Robert Tubb on 03/10/2012. +// +// + +#include "grid.h" + + +#include <sstream> + +extern PresetManager presetManager; +extern EventLogger eventLogger; +//-------------------------------------------------------------- +Grid::Grid(): maxValue(pow(32.0,7.0)-1), minValue(60), paramsPerDim(5), paramBitDepth(7){ + +} +//-------------------------------------------------------------- +//-------------------------------------------------------------- +Grid::~Grid(){ + +} +void Grid::init(){ + //maxValue = pow(32.0,7.0)-1; + //minValue = 60; // number of 1-size divisions at smallest scale + maxZoom = false; + minZoom = false; + + codeLength = pow(2.0,paramsPerDim); + + pixSize.setCoord(ofGetWidth(), ofGetHeight()); + + //set scale and position to mid way + scale = pow(32.0,6.0); + + + size.setCoord(pixSize.x*scale, pixSize.y*scale); + centre.setCoord(maxValue/2 , maxValue/2); + topLeft.setCoord(centre.x - size.x/2, centre.y - size.y/2); + + + makeCode(); + + // set a starting param value, find coord that does it. + vector<int> params(paramsPerDim*2); + for(int i = 0;i<2*paramsPerDim;i++){ + midiCC[i] = 12; + params[i] = 12; + } + TwoVector coord = calculateCoordFromParams(params); + setCoord(coord); + + viewWasChanged(); + + + +} + +template <typename T> int sgn(T val) { + return (T(0) < val) - (val < T(0)); +} + +void Grid::makeCode(){ + + ////////////////////////////////~~~,,,,,,,,......... + ////////// gray code generation + ////// + /// + // TODO 5bit specific + // transition sequence.... what a palaver! only need to do once though. + int trans[] = {0,1,2,3,0,4,2,1,0,3,2,1,0,4,2,3,0,1,2,3,0,4,2,1,0,3,2,1,0,4,2,3}; + + + int code[codeLength][paramsPerDim]; // start with normal array + + + + for(int j=0; j<paramsPerDim; j++){ + code[0][j] = 0; + } + + for(int i=0; i < codeLength-1; i++){ // TODO went off end?? + transSeq.push_back(trans[i]); // member vector + for(int j=0; j<paramsPerDim; j++){ + + if (j == abs(trans[i])){ + code[i+1][j] = !code[i][j]; + }else{ + code[i+1][j] = code[i][j]; + } + } + + } + + for(int i=0; i < codeLength; i++){ // fill vector + + vcode.push_back(vector<bool>()); + + for(int j=0; j<paramsPerDim; j++){ + vcode[i].push_back(code[i][j]); + } + } + + // now try with iterators to print... + vector< vector<bool> >::iterator cit; + //vector<bool>::iterator bit; + vector<bool>::iterator bit; + int i = 0; + for(cit=vcode.begin(); cit!=vcode.end() ; cit++){ // fill vector + i++; + cout << i << " = "; + bit = (*cit).begin(); + for(bit=(*cit).begin(); bit!=(*cit).end() ; bit++){ + + cout << *bit; + } + cout << "\n"; + + } + /* + // codeToInt unit test + vector<bool> aCode = vcode[12]; + int result = grayToInt(aCode); + cout << "GRAY TO INT : " << result << "\n"; + + cout << "-------------------------------\n"; + + // base32toFloat unit test + + vector<int> test32 = coordTobase32(869437.0); + double cresult = base32toCoord(test32); + cout << "base32toCoord : " << cresult << "\n"; + + cout << "-------------------------------\n"; + + + + // midiToGray unit test + + vector<vector<bool> > incodes(paramBitDepth, vector<bool>(paramsPerDim)); + for(int i=0;i<7;i++){ + incodes[i] = vcode[i+5]; + } + + vector<int> midiTest; + midiTest = grayToMidi(incodes); + vector<vector<bool> > outcodes = midiToGray(midiTest); + + vector< vector<bool> >::iterator cit1; + //vector<bool>::iterator bit; + vector<bool>::iterator bit1; + cout << "midiToGray Unit test\n"; + for(int i=0;i<paramBitDepth;i++){ // fill vector + + for(int j=0;j<paramsPerDim;j++){ + + cout << (incodes[i][j] == outcodes[i][j]) << ","; + } + cout << "\n"; + + } + cout << "-------------------------------\n"; + + + // whole process unit test(?) + + TwoVector inCoord(888999777,777666555); + vector<int> checkParam; + checkParam = calculateParamsFromCoord(inCoord); + for(int i=0; i<2*paramsPerDim;i++){ + cout << checkParam[i] << "_"; + } + TwoVector outCoord = calculateCoordFromParams(checkParam); + cout << "Unit TEst coord = " << outCoord.x << "," << outCoord.y << "\n"; +*/ + +} +//-------------------------------------------------------------- +void Grid::draw(){ // draw lines + // TODO too friggin long + + //scale++; + // nice loopy thing + int power = 0; + + // these get big! + double divsr; + double yl,xl; + double gridSize = 0; + + double firstLineXPos, lastLineXPos,firstLineYPos, lastLineYPos, remleft, xoffset, yoffset = 0.0; + double xstart, xfinish, ystart,yfinish; + // these don't + int xpos, ypos = 0; + + float alpha; + bool done = false; + float markpow = 32.0; // power that denotes next grid markings + int lineWidth = 0; + int colCycle = 0; + + + // loop thru powers of (base?) to determine which should be shown as grids + while (!done){ + gridSize = pow(markpow,power); + + colCycle = power % 7; + + divsr = size.x / gridSize; + + // if (divisor i.e. number of lines is less than 1000 + if( divsr >= 1 && divsr < 1000){ + + // calculate transparency + float visCont = log10(divsr); // 0 if only 1 line, 3 if 1000 lines + alpha = 90*(3 - visCont); + ofSetLineWidth(lineWidth); + + // cycle colors for different scales + if(colCycle == 0){ + ofSetColor(255,255,255,alpha); + }else if(colCycle == 1){ + ofSetColor(255,0,0,alpha); + }else if(colCycle == 2){ + ofSetColor(0,0,255,alpha); + }else if(colCycle == 3){ + ofSetColor(0,255,0,alpha); + }else if(colCycle == 4){ + ofSetColor(255,0,255,alpha); + }else if(colCycle == 5){ + ofSetColor(0,255,255,alpha); + }else if(colCycle == 6){ + ofSetColor(255,255,0,alpha); + }else if(colCycle == 7){ + ofSetColor(255,255,255,alpha); + }else{ + cout << "err colour messed up\n"; + } + + + // draw level numbers associated with each color. This would not be true if markpow wasnt 2^d + ////////-------///////// + /* + temp << "THIS LEVEL = " << (int)pow(2.0,power) << " "; + string s = temp.str(); + ofDrawBitmapString( s, 10, line ); + line+=30; + temp.str(""); + *////////-------///////// + + // draw presets at this level + // fill in smallest squares if they contain a preset + // how to do this efficiently? + + + if(topLeft.x < 0.0){ + firstLineXPos = 0.0; + xoffset = firstLineXPos - topLeft.x; + xstart = xoffset/scale; + }else{ + firstLineXPos = topLeft.x; + // kinda float version of % operator + remleft = ceil(firstLineXPos/gridSize); + xoffset = (remleft * gridSize) - topLeft.x; + xstart = 0; + } + if(topLeft.x + size.x > maxValue){ + lastLineXPos = maxValue+1 - topLeft.x; + + + }else{ + lastLineXPos = size.x; + + } + xfinish = lastLineXPos/scale; + + //////////------------------------ + // same for y + + if(topLeft.y < 0.0){ + firstLineYPos = 0.0; + yoffset = firstLineYPos - topLeft.y; + ystart = yoffset/scale; + }else{ + firstLineYPos = topLeft.y; + // kinda float version of % operator + remleft = ceil(firstLineYPos/gridSize); + yoffset = (remleft * gridSize) - topLeft.y; + ystart = 0; + } + if(topLeft.y + size.y > maxValue){ + lastLineYPos = maxValue+1 - topLeft.y; + + }else{ + lastLineYPos = size.y; + + } + yfinish = lastLineYPos/scale; + // ------------------------------------------- + // now draw + for(xl = xoffset; xl <= (lastLineXPos); xl+= gridSize){ + + xpos = xl/scale; + ofLine(xpos, ystart, xpos, yfinish); + + } + + for(yl = yoffset; yl <= (lastLineYPos); yl+= gridSize){ + + ypos = yl/scale; + ofLine(xstart, ypos, xfinish, ypos); + } + + + }else if (divsr < 1){ + // ignore... + done = true; + } + + power++; + } + //cout << "draw done" << "\n"; + //displayInfo(); + + drawPresets(); + ////////-------///////// + + ////////-------///////// + + // draw centre cross hairs + ofSetColor(255, 0, 0); + ofNoFill(); + ofLine(pixSize.x/2-20, pixSize.y/2, pixSize.x/2+20, pixSize.y/2); + ofLine(pixSize.x/2, pixSize.y/2-20, pixSize.x/2, pixSize.y/2+20); + ofEllipse(pixSize.x/2, pixSize.y/2, 20, 20); + ofFill(); + ////////-------//////// + /* + ostringstream temp; + temp << "Centre x = " << centre.x << "\n y = " << centre.y << " "; + string s = temp.str(); + ofDrawBitmapString( s, pixSize.x/2+10, pixSize.y/2+10 ); + */ +} +TwoVector Grid::coordToPixel(TwoVector coord){ + TwoVector pix; + pix.x = (coord.x - topLeft.x)/scale; + pix.y = (coord.y - topLeft.y)/scale; + return pix; + +} + +//----------------------------------------------------------------------- +void Grid::drawPresets(){ + vector<TwoVector> points; + TwoVector pos; + points = presetManager.getPresetsInRange(topLeft, topLeft + size); + vector<TwoVector>::iterator piter; + for(piter = points.begin(); piter < points.end(); piter++){ + ofSetColor(255, 255, 255, 200); + pos = coordToPixel(*piter); + ofCircle(pos.x, pos.y, 2); + + } +} + +//----------------------------------------------------------------------- +void Grid::displayInfo(){ + + // display some "useful information" + + ofSetColor(255,255,255,255); + + ostringstream temp; + int line = 10; // text output pos + + + ////////-------///////// + temp << "scale = " << scale << " "; + string s = temp.str(); + ofDrawBitmapString( s, 10, line ); + line+=30; + temp.str(""); + ////////-------///////// + temp << "Top Left = " << topLeft.x << "," << topLeft.y << " "; + s = temp.str(); + ofDrawBitmapString( s, 10, line ); + line+=60; + temp.str(""); + + ////////-------///////// + temp << "View Size = " << size.x << "," << size.y << " "; + s = temp.str(); + ofDrawBitmapString( s, 10, line ); + line+=60; + temp.str(""); + + ////////-------///////// + + for(int i=0;i<10;i++){ // TODO 5bit specific + temp << midiCC[i] << " "; + s = temp.str(); + ofDrawBitmapString( s, 10, line ); + line+=20; + temp.str(""); + } +} + //-------------------------------------------------------------- +void Grid::update(){ // ? + // "update" bit of a crap name - all we do here is calculate the dimension params from the x,y position + + +} +//-------------------------------------------------------------- +void Grid::move(TwoVector moveP){ + // numspacing, pixelspacing stay the same + + // convert pixels to surf units + TwoVector moveS; + moveS = moveP * scale; + + topLeft = topLeft - moveS; // - because moving to the right means taking away from offset + centre = centre - moveS; + + viewWasChanged(); + eventLogger.logEvent(-1, centre, scale); + +} +//-------------------------------------------------------------- +void Grid::zoom(float factor){ + if(maxZoom && factor > 1.0){ + return; + + } + if(factor < 1.0){ + maxZoom = false; + } + if(minZoom && factor < 1.0){ + return; + + } + if(factor > 1.0){ + minZoom = false; + } + scale = scale*factor; // simple eh? + + // update view size using centre + // and scale... + size.x = size.x*factor; // zooming in, size gets SMALLER (view less) + size.y = size.y*factor; + + + + viewWasChanged(); + eventLogger.logEvent(-2, centre, scale); + +} +void setMaxZoom(){ // got to smallest (white) + +} +//-------------------------------------------------------------- +void setMinZoom(){ // go to entire space (orange) + +} +//-------------------------------------------------------------- +void Grid::viewWasChanged(){ + checkLimits(); + // and calculate new params? + + vector<int> params = calculateParamsFromCoord(centre); + for(int i = 0;i<2*paramsPerDim;i++){ + midiCC[i] = params[i]; + } + // update sliders if nec. + +} + +//-------------------------------------------------------------- +void Grid::checkLimits(){ + // check for maximum zoom level + // TODO: DODGY + + if(size.x > maxValue*2.0){ + cout << "maxZoom\n"; + maxZoom = true; + size.x = maxValue*2.0; + // need to also set y size back to + } + if(size.y > maxValue*2.0){ + cout << "maxZoom\n"; + maxZoom = true; + size.y = maxValue*2.0; + } + + if(size.x < minValue){ + cout << "min Zoom\n"; + minZoom = true; + size.x = minValue; + // need to also set y size back to + } + if(size.y < minValue){ + minZoom = true; + cout << "min Zoom\n"; + size.y = minValue; + } + + scale = size.x/pixSize.x; + size.y = scale * pixSize.y; + + topLeft.x = centre.x - size.x/2; + topLeft.y = centre.y - size.y/2; + // check for negatives + + // allow centre to be at limits + if((topLeft.x + size.x*0.5) < 0.0){ + cout << "left Wall\n"; + topLeft.x = 0.0 - size.x*0.5; + centre.x = 0.0; + } + + if(topLeft.y + size.y*0.5 < 0.0) { + cout << "top Wall\n"; + topLeft.y = 0.0 - size.y*0.5; + centre.y = 0.0; + } + + // does topleft refer to lines or view? + + // check max + if(topLeft.x + size.x/2 > maxValue){ + cout << "right Wall\n"; + topLeft.x = maxValue - size.x/2; + centre.x = maxValue; + } + if(topLeft.y + size.y/2 > maxValue) { + cout << "bottom Wall\n"; + topLeft.y = maxValue - size.y/2; + centre.y = maxValue; + } + +} +//-------------------------------------------------------------- +void Grid::checkConsistencies(){ + // debug function to check all the parameters are consistent maybe + +} +//-------------------------------------------------------------- +void Grid::setCoord(TwoVector coord){ + + centre = coord; + viewWasChanged(); +} +//-------------------------------------------------------------- +TwoVector Grid::getCoord(){ + + return centre; +} +//-------------------------------------------------------------- +vector<int> Grid::getParams(){ + // return a vector with midiCCs in + // should we store params somewhere and use this as a low computation get ? + vector<int> params(2*paramsPerDim,0); + // + for(int i = 0;i<2*paramsPerDim;i++){ + params[i] = midiCC[i]; + } + return params; +} +//-------------------------------------------------------------- +void Grid::setParams(vector<int> params){ + // input midiCCs, and go to the appropriate coordinate + + for(int i = 0;i<2*paramsPerDim;i++){ + midiCC[i] = 64; + } + TwoVector coord = calculateCoordFromParams(params); + setCoord(coord); + + viewWasChanged(); + +} +//-------------------------------------------------------------- +TwoVector Grid::calculateCoordFromParams(vector<int> params) const{ + + vector<int> ccValueX(paramsPerDim); + vector<int> ccValueY(paramsPerDim); + for(int i=0;i<paramsPerDim;i++){ + ccValueX[i] = params[i]; + ccValueY[i] = params[i+paramsPerDim]; + } + vector<vector <bool> > codesX = midiToGray(ccValueX); + vector<vector <bool> > codesY = midiToGray(ccValueY); + + vector<int> base32X = codesToBase32(codesX); + vector<int> base32Y = codesToBase32(codesY); + + TwoVector result; + result.x = base32toCoord(base32X); + result.y = base32toCoord(base32Y); + return result; +} + +//-------------------------------------------------------------- +vector<int> Grid::calculateParamsFromCoord(TwoVector coord) const{ + // some arrays in reverse order of power from normal numbers! 1,2,4, + + // centre to base 32 + if (coord.x > maxValue || coord.y > maxValue){ + cout << "calculateParams Error: centre double value is too large" << "\n"; + vector<int> empty; + return empty; + } + + //-------------------------- + // X + vector<int> base32x = coordTobase32(coord.x); // 7 numbers from 0 to 31 + vector<vector <bool> > grayCodesX; + + int size = base32x.size(); + for(int i=0;i<size;i++){ + grayCodesX.push_back(intToGray(base32x[i])); + } + + vector<int> result; + result = grayToMidi(grayCodesX); + //-------------------------- + // AND FOR Y + vector<int> base32y = coordTobase32(coord.y); + vector<vector <bool> > grayCodesY; + + size = base32y.size(); + for(int i=0;i<size;i++){ + grayCodesY.push_back(intToGray(base32y[i])); + } + + vector<int> resultY; + resultY = grayToMidi(grayCodesY); + + // concatenate + result.insert( result.end(), resultY.begin(), resultY.end() ); + return result; +} +//------------------------------------------------------------------- + +// for 1 dimension!!! i.e. call this twice +vector<int> Grid::grayToMidi(vector<vector <bool> > grayCodes) const{ + + // gray to midi CC values + // loop thru the scales to build up a CC number per dimension + int midiCCresult[paramsPerDim]; // TODO dims specific + for(int i=0;i<paramsPerDim;i++){ + midiCCresult[i] = 0; + } + + int bin = 1; + bin = bin << grayCodes.size()-1; + + int midP = 0; + + vector<vector <bool> >::iterator piter = grayCodes.begin(); + for(;piter < grayCodes.end();piter++){ // each lesser power of 2 + midP = 0; // reset + vector<bool>::iterator diter = (*piter).begin(); + for(; diter <= (*piter).end();diter++){ // each one is different dimension + int ig = int(*diter); // convert binary to int + //cout << "ig: " << ig; + midiCCresult[midP] += ig*bin; // mult by power of two + midP++; + } + bin = bin >> 1; // next power of 2 down + + } + + // put in vector + vector<int> result; + for(int i=0;i<paramsPerDim;i++){ + result.push_back(midiCCresult[i]); + } + + return result; + + +} + + +//-------------------------------------------------------------- + +vector<bool> Grid::intToGray(int num, int dimToTravel) const{ + + // dimToTravel - this is the dimension that we want the walk to traverse, i.e. the last non zero digit of the code + // so swap it for 3 to produce correct orientation + + // just use look up table... until it gets huuuge. + vector<bool> grayCode = vcode[num]; + grayCode[3] = vcode[num][dimToTravel]; + grayCode[dimToTravel] = vcode[num][3]; + return grayCode; +} +//-------------------------------------------------------------- +vector<int> Grid::walkDiff(vector<bool> left, vector<bool> right){ + // horrible + vector<int> result(2,0); + + int size = left.size(); + for(int i = 0; i < size; i++){ + if(left[i] && !right[i]){ // 1 - 0 + // dim + result[0] = i; + result[1] = 1; + }else if(!left[i] && right[i]){ // 0 - 1 + result[0] = i; + result[1] = -1; + }else{ // equal do nothing + + + } + } + + return result; +} + +//-------------------------------------------------------------- +/* +breaks down float into a base 32 number (2^D) +each of these is converted to gray code +this is then converted to 10 parameters, where each 32-digit becomes separate power of 2 + so "zoom" grid 32-patches are converted to 2-scales. 1,2,4,8,16,32,64,(128?) biggest number is 32^7 +*/ +vector<int> Grid::coordTobase32(double value) const{ + //double base = 32.0; + if(value < 0.0){ + cout << "coordTobase32 error: input value is negative\n"; + value = 0.0; + }else if(value > maxValue){ + cout << "coordTobase32 error: input value too big!\n"; + } + double rem, divdr = 0.0; + int digit32; + + // what power of 32 to start at? + int maxpow = 7; // midi cc specific + vector<int> result; + + rem = value; + for(;maxpow >=0;maxpow--){ + // repeatedly get digit and remainder. This is exactly what we're doing in draw !?... could put all this in one place? + divdr = pow((double)codeLength,(double)maxpow); + digit32 = floor(rem/divdr); + rem = rem - digit32*divdr; + result.push_back(digit32); // array, biggest index is smallest power + } + // at this point rem should be fractional... use for interp? + + return result; +} +//-------------------------------------------------------------- + +// WHY HERE XCODE? +vector<int> Grid::codesToBase32(vector<vector<bool> > inCodes) const{ + vector<int> result; + for(int i=0;i<paramBitDepth;i++){ + result.push_back(grayToInt(inCodes[i])); + } + return result; +} +//-------------------------------------------------------------- + +int Grid::grayToInt(vector<bool> incode) const{ + // look for match in table + + int s = vcode.size(); + + for(int i=0; i<s;i++){ // fill vector + if(vcode[i] == incode){ + return i; + } + + } + cout << "grayToInt error: no matching code found!"; + return -1; +} +//-------------------------------------------------------------- +double Grid::base32toCoord(vector<int> base32Digs) const{ + // build up the big float from a base 32 number + double result = 0.0; + + // what power of 32 to start at? + int mpow = base32Digs.size() - 1; // should be 7... + + for(int p=0;p<=mpow;p++){ // biggest index is smallest power + result += ((double)base32Digs[p]) * pow(32.0, (double)mpow-p); + + } + return result; + +} +//-------------------------------------------------------------- +// for 1 dimension - takes in 5 cc params and outputs 7 codes +vector<vector <bool> > Grid::midiToGray(vector<int> ccValue) const{ + int pow2 = 1 << (paramBitDepth-1); + + vector<int> aCode(paramsPerDim); + vector<vector<int> > theXCodes(paramBitDepth,aCode); + + // build up binary gray code representations from the bits of the midi ccs + + vector<vector<bool> > theCodes(paramBitDepth, vector<bool>(paramsPerDim)); + + // x + for(int p=0;p<paramBitDepth;p++){ + + for(int i=0;i<paramsPerDim;i++){ + + bool bit = (pow2 == (ccValue[i] & pow2)); + theCodes[p][i] = bit; + } + pow2 = pow2 >> 1; + + } + return theCodes; +} +//-------------------------------------------------------------- +//-------------------------------------------------------------- +//-------------------------------------------------------------- \ No newline at end of file
--- a/presetManager.h Mon Dec 03 18:29:07 2012 +0000 +++ b/presetManager.h Tue Dec 04 18:36:00 2012 +0000 @@ -23,18 +23,34 @@ int presetID; string name; + long long savetime; + double timemsd = [NSDate timeIntervalSinceReferenceDate]; + TwoVector coordinates; Preset(TwoVector acoord, string aname,int aID){ coordinates = acoord; name = aname; presetID = aID; + + timemsd = [NSDate timeIntervalSinceReferenceDate]; + savetime = (long long)(timemsd*1000); }; Preset(int aID){ coordinates.setCoord(0.0,0.0); name = "Blank"; presetID = aID; + timemsd = [NSDate timeIntervalSinceReferenceDate]; + savetime = (long long)(timemsd*1000); + + }; + + Preset(TwoVector acoord, string aname,int aID, long long stime){ + coordinates = acoord; + name = aname; + presetID = aID; + savetime = stime; }; @@ -42,20 +58,6 @@ //--------------------------------------------------------------------------- -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; @@ -66,14 +68,53 @@ vector<Preset *> thePresets; // we want vector ? or list? pointers using new? int addPreset(TwoVector coord, string name); // returns id or negative error number + int loadPreset(const TwoVector coord, const string name, long long stime); + TwoVector recallPreset(int presetID); // by name ? id? TwoVector recallPreset(string name); // by name ? id? vector<TwoVector > getPresetsInRange(TwoVector min, TwoVector max); + void printAll(); void startupLoadAll(); // get stuff from XML void exitAndSaveAll(); // save to XML, delete presets array (?) + void deleteAll(); PresetManager(); }; + +//--------------------------------------------------------------------------- +inline ostream& operator<<(ostream & os, const Preset& p){ + os.setf(ios_base::fixed,ios_base::floatfield); + os.precision(1); + + os << p.savetime << ',' << p.coordinates.x << ',' << p.coordinates.y << '\n'; + + return os; +} + + //--------------------------------------------------------------------------- + inline istream& operator>>(istream & is, PresetManager& p) + { + //um + string pname = "BLANK"; + char delim; + double px, py; + long long stime; + + + is.setf(ios_base::fixed,ios_base::floatfield); + is.precision(1); + + is >> stime >> delim >> px >> delim >> py; + if(!is){ + cout << "problem reading preset file"; + return(is); + } + TwoVector pcoord(px,py); + int n = p.loadPreset(pcoord, pname, stime); + cout << "read preset : " << n << '\n'; + return(is); + } + #endif /* defined(__oscSenderExample__presetManager__) */
--- a/presetManager.mm Mon Dec 03 18:29:07 2012 +0000 +++ b/presetManager.mm Tue Dec 04 18:36:00 2012 +0000 @@ -16,11 +16,22 @@ PresetManager::PresetManager(){ timesOpened = 0; + nextID = 0; startupLoadAll(); - - - nextID = 0; - + +} +//--------------------------------------------------------------------------- +void PresetManager::deleteAll(){ + thePresets.clear(); +} +//--------------------------------------------------------------------------- +void PresetManager::printAll(){ + cout << "ALL PRESETS: \n"; + vector<Preset *>::iterator presetIter; + for(presetIter = thePresets.begin(); presetIter < thePresets.end(); presetIter++){ + cout << **presetIter << "\n"; + + } } //--------------------------------------------------------------------------- @@ -51,6 +62,15 @@ return nextID++; } //--------------------------------------------------------------------------- + +int PresetManager::loadPreset(const TwoVector coord, const string name, long long stime){ + + + thePresets.push_back(new Preset(coord, name,nextID, stime)); + // if ok + return nextID++; +} +//--------------------------------------------------------------------------- vector<TwoVector > PresetManager::getPresetsInRange(const TwoVector min, const TwoVector max){ //return all the coordinates. oh and names (displayed at certain scales?). @@ -74,16 +94,20 @@ // load file string fname = ofxiPhoneGetDocumentsDirectory() + "presets.dat"; - char *fileName = (char*)fname.c_str(); - ifstream from(fileName); - string line; + ifstream presetFile(fname.c_str()); // simply prints file - while(from >> line){ - cout << line << "\n"; - + int i= 0; + if(!presetFile){ + cout<<"no preset file"; + return; } - + while(presetFile >> *this){ + cout << "loaded" << i++ << " presets\n"; + // parse line + + } + presetFile.close(); timesOpened++; @@ -91,7 +115,7 @@ //--------------------------------------------------------------------------- void PresetManager::exitAndSaveAll(){ ofFile presetFile(ofxiPhoneGetDocumentsDirectory() +"presets.dat",ofFile::WriteOnly); - + cout << "Exit and save presets\n"; vector<Preset *>::iterator presetIter; @@ -99,8 +123,6 @@ //vector<int> params; //params = theGridView.calculateParamsFromCoord((*presetIter)->coordinates); presetFile << **presetIter << "\n"; - cout << **presetIter << "\n"; - } presetFile.close();
--- a/testApp.mm Mon Dec 03 18:29:07 2012 +0000 +++ b/testApp.mm Tue Dec 04 18:36:00 2012 +0000 @@ -34,7 +34,7 @@ stringstream sstr; sstr << str; sstr >> ttest; - cout << "ttest: " << ttest.x << "\n"; + cout << "ttest: " << ttest << "\n"; prevTouch0.setCoord(1,2); @@ -354,10 +354,13 @@ //-------------------------------------------------------------- void testApp::exit(){ + + presetManager.exitAndSaveAll(); core.exit(); - presetManager.exitAndSaveAll(); + delete standardGUI; delete zoomGUI; + cout << "exit done \n"; } //--------------------------------------------------------------