annotate testApp.mm @ 43:b91a1859829a

used UIkit sliders
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Fri, 19 Apr 2013 18:50:04 +0100
parents 3d627dce8bf0
children a1e75b94c505
rev   line source
rt300@0 1 #include "testApp.h"
rt300@2 2
rt300@39 3
rt300@0 4 extern Grid theGridView;
rt300@0 5 extern PresetManager presetManager;
rt300@1 6 extern EventLogger eventLogger;
rt300@3 7 extern Frequencer frequencer;
rt300@35 8 extern Hilbert hilbert;
rt300@9 9
rt300@24 10 const vector<string> parameterNames;
rt300@24 11
rt300@24 12 const string sliderParamNames[10] = {"Transpose", "1/4 note","1/6 note","1/7 note","1/8 note","Waveform", "Filter Type","Filter Freq", "Envelope","FM amt"};
rt300@24 13 //const vector<const string> v(ra[0],ra[1]);
rt300@24 14
rt300@43 15 //--------------------------------------------------------------
rt300@43 16 void testApp::setup(){
rt300@43 17
rt300@43 18 // initilaise
rt300@43 19
rt300@43 20 initialiseVariables();
rt300@43 21 initialiseGUIs();
rt300@43 22
rt300@43 23 // initialise PD
rt300@43 24
rt300@43 25 int ticksPerBuffer = 8; // 8 * 64 = buffer len of 512
rt300@43 26 core.setup(2, 1, 44100, ticksPerBuffer);
rt300@43 27
rt300@43 28 // setup OF sound stream
rt300@43 29 ofSoundStreamSetup(2, 1, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 3);
rt300@43 30
rt300@43 31 tsc = [[TimedSessionController alloc] init];
rt300@43 32 [tsc setAppRef:(id)this];
rt300@43 33
rt300@43 34 //--------------------------------------
rt300@43 35 // load stuff
rt300@43 36 loadSequences();
rt300@43 37
rt300@43 38 // load presets
rt300@43 39 presetManager.startLoadAll();
rt300@43 40
rt300@43 41 eventLogger.startLoadAll();
rt300@43 42 //--------------------------------------
rt300@43 43
rt300@43 44 // now do things that will affect the start up state of the app
rt300@43 45
rt300@43 46 /*
rt300@43 47 if(eventLogger.questionnaireCompleted){ // then we go into do-what-you-like mode
rt300@43 48
rt300@43 49 freeUseMode();
rt300@43 50 }else{
rt300@43 51 // then we're in timed session mode
rt300@43 52 showIntro();
rt300@43 53 }
rt300@43 54 */
rt300@43 55 freeUseMode();
rt300@43 56 // GO
rt300@43 57 paused = false;
rt300@43 58 eventLogger.logEvent(APP_STARTED);
rt300@43 59 }
rt300@24 60
rt300@43 61 //-----------------------------------------------------------------------------
rt300@35 62
rt300@7 63 //DeviceID3523537000
rt300@42 64 void testApp::initialiseVariables(){
rt300@16 65 paused = true;
rt300@39 66 sendMIDIAndOSC = false;
rt300@37 67
rt300@16 68 ofBackground( 0, 0, 0 );
rt300@0 69 ofEnableAlphaBlending();
rt300@36 70 currentSequence = 0;
rt300@40 71 //ofEnableSmoothing();
rt300@37 72
rt300@29 73 // open an outgoing connection to HOST:PORT for OSC
rt300@29 74
rt300@29 75 sender.setup( OSC_HOST, OSC_PORT );
rt300@28 76 ofSetFrameRate(50);
rt300@43 77
rt300@6 78 lastMoveTime = ofGetSystemTimeMicros();
rt300@0 79 prevTouchX = 0;
rt300@0 80 prevTouchY = 0;
rt300@0 81
rt300@0 82 xLocked = false;
rt300@0 83 yLocked = false;
rt300@0 84
rt300@0 85 numActiveTouches = 0;
rt300@3 86 touch0.setCoord(17./7., 2./3.);
rt300@0 87 touch1.setCoord(10,20);
rt300@3 88
rt300@0 89 prevTouch0.setCoord(1,2);
rt300@0 90 prevTouch1.setCoord(10,20);
rt300@0 91 prevDist = 10;
rt300@16 92 slowFactor = 0.98;
rt300@27 93 preventingMovePostScroll = false;
rt300@16 94
rt300@16 95 // the 5 harmonics for the frequencer
rt300@16 96 freqIndexes.push_back(0);
rt300@16 97 freqIndexes.push_back(4);
rt300@16 98 freqIndexes.push_back(6);
rt300@16 99 freqIndexes.push_back(7);
rt300@16 100 freqIndexes.push_back(8);
rt300@16 101
rt300@16 102
rt300@42 103 ofxiPhoneSetOrientation( OFXIPHONE_ORIENTATION_PORTRAIT );
rt300@42 104 ofxiPhoneExternalDisplay::mirrorOn();
rt300@42 105 }
rt300@43 106 //---------------------------------------------------------
rt300@42 107 void testApp::initialiseGUIs(){
rt300@0 108 theGridView.init();
rt300@0 109
rt300@43 110
rt300@43 111 //SLIDER
rt300@24 112 setupSliderGui();
rt300@43 113 sliderGUI->setVisible(false);
rt300@0 114
rt300@0 115 // initial slider vals
rt300@0 116 for(int i=0; i<10;i++){
rt300@0 117 sliderVals.push_back(64);
rt300@0 118 }
rt300@37 119
rt300@37 120
rt300@24 121 // set up iOS gui stuff
rt300@24 122 bottomTabViewController = [[BottomTabViewController alloc] initWithNibName:@"BottomTabViewController" bundle:nil];
rt300@24 123 [ofxiPhoneGetGLParentView() addSubview:bottomTabViewController.view];
rt300@24 124
rt300@24 125 [bottomTabViewController setAppRef:(id)this];
rt300@24 126 bottomTabViewController.view.frame = CGRectMake(0,getHeight()-44,getWidth(),44);
rt300@29 127 bottomTabViewController.view.hidden = YES;
rt300@37 128
rt300@24 129 /////
rt300@24 130
rt300@24 131 topButtonViewController = [[TopButtonViewController alloc] initWithNibName:@"TopButtonViewController" bundle:nil];
rt300@24 132 [ofxiPhoneGetGLParentView() addSubview:topButtonViewController.view];
rt300@24 133 [topButtonViewController setAppRef:(id)this];
rt300@24 134 [topButtonViewController show:(id)this];
rt300@24 135 topButtonViewController.view.frame = CGRectMake(0,0,getWidth(),44);
rt300@24 136
rt300@25 137 usernameAlertViewController = [[UsernameAlertViewController alloc] init];
rt300@42 138 [usernameAlertViewController setAppRef:(id)this];
rt300@26 139
rt300@27 140 helpViewController = [[HelpViewController alloc] initWithNibName:@"HelpViewController" bundle:nil];
rt300@27 141 [ofxiPhoneGetGLParentView() addSubview:helpViewController.view];
rt300@27 142 [helpViewController setAppRef:(id)this];
rt300@27 143 helpViewController.view.hidden = YES;
rt300@27 144
rt300@43 145 //SLIDER
rt300@43 146
rt300@42 147 sliderViewController = [[SliderViewController alloc] initWithNibName:@"SliderViewController" bundle:nil];
rt300@42 148 [ofxiPhoneGetGLParentView() addSubview:sliderViewController.view];
rt300@42 149 [sliderViewController setAppRef:(id)this];
rt300@43 150 sliderViewController.view.frame = CGRectMake(0,getHeight()-43 - 325,getWidth(),325);
rt300@43 151 [sliderViewController show:(id)this];
rt300@43 152
rt300@36 153
rt300@42 154 setAllGUISliders(theGridView.getParams());
rt300@25 155
rt300@42 156 }
rt300@43 157 //--------------------------------------------------------------------------
rt300@42 158 void testApp::initialiseMIDI(){
rt300@36 159
rt300@39 160 /////////////////////////
rt300@39 161 // MIDI
rt300@39 162
rt300@39 163 midiChannel = 7;
rt300@39 164 midiOffset = 0;
rt300@39 165
rt300@39 166 // enables the network midi session between iOS and Mac OSX on a
rt300@39 167 // local wifi network
rt300@39 168 //
rt300@39 169 // in ofxMidi: open the input/outport network ports named "Session 1"
rt300@39 170 //
rt300@39 171 // on OSX: use the Audio MIDI Setup Utility to connect to the iOS device
rt300@39 172 //
rt300@39 173 ofxMidi::enableNetworking();
rt300@39 174
rt300@39 175 // list the number of available input & output ports
rt300@39 176 ofxMidiIn::listPorts();
rt300@39 177 ofxMidiOut::listPorts();
rt300@39 178
rt300@39 179 // create and open input ports
rt300@39 180 for(int i = 0; i < ofxMidiIn::getNumPorts(); ++i) {
rt300@39 181
rt300@39 182 // new object
rt300@39 183 inputs.push_back(new ofxMidiIn);
rt300@39 184
rt300@39 185 // set this class to receive incoming midi events
rt300@39 186 inputs[i]->addListener(this);
rt300@39 187
rt300@39 188 // open input port via port number
rt300@39 189 inputs[i]->openPort(i);
rt300@39 190 }
rt300@39 191
rt300@39 192 // create and open output ports
rt300@39 193 for(int i = 0; i < ofxMidiOut::getNumPorts(); ++i) {
rt300@39 194
rt300@39 195 // new object
rt300@39 196 outputs.push_back(new ofxMidiOut);
rt300@39 197
rt300@39 198 // open input port via port number
rt300@39 199 outputs[i]->openPort(i);
rt300@39 200 }
rt300@39 201
rt300@39 202 // set this class to receieve midi device (dis)connection events
rt300@39 203 ofxMidi::setConnectionListener(this);
rt300@39 204
rt300@39 205 // END MIDI
rt300@42 206
rt300@42 207 }
rt300@24 208
rt300@24 209
rt300@24 210 //--------------------------------------------------------------
rt300@24 211 void testApp::exit(){
rt300@37 212
rt300@25 213 presetManager.exitAndSaveAll();
rt300@25 214 eventLogger.exitAndSave();
rt300@37 215
rt300@24 216 core.exit();
rt300@24 217
rt300@25 218 // are these handled automatically?
rt300@25 219 //[introViewController release];
rt300@25 220 //[topButtonViewController release];
rt300@25 221 //[bottomTabViewController release];
rt300@24 222
rt300@39 223 // clean up MIDI
rt300@39 224 for(int i = 0; i < inputs.size(); ++i) {
rt300@39 225 inputs[i]->closePort();
rt300@39 226 inputs[i]->removeListener(this);
rt300@39 227 delete inputs[i];
rt300@39 228 }
rt300@39 229
rt300@39 230 for(int i = 0; i < outputs.size(); ++i) {
rt300@39 231 outputs[i]->closePort();
rt300@39 232 delete outputs[i];
rt300@39 233 }
rt300@39 234
rt300@43 235 //SLIDER
rt300@24 236 delete sliderGUI;
rt300@37 237
rt300@24 238 cout << "exit done \n";
rt300@0 239 }
rt300@24 240
rt300@24 241 //--------------------------------------------------------------
rt300@3 242 #pragma mark GUI
rt300@16 243 //--
rt300@16 244 float testApp::getWidth(){
rt300@16 245 // depends on orientation
rt300@16 246 return ofGetWidth();
rt300@16 247
rt300@16 248 }
rt300@16 249 float testApp::getHeight(){
rt300@16 250 // depends on orientation
rt300@16 251 return ofGetHeight();
rt300@16 252
rt300@16 253 }
rt300@24 254 #pragma mark GUI
rt300@24 255 ////////////////////////////
rt300@24 256 // These functions called from iOS toolbars
rt300@24 257 //--------------------------------------------------------------
rt300@24 258 void testApp::lockSequencerPressed(bool locked){
rt300@24 259 theGridView.shiftCentreToSnapped();
rt300@24 260 xLocked = locked;
rt300@39 261 eventLogger.logEvent(SEQ_LOCKED); // TODO whatabout unlock?
rt300@25 262
rt300@24 263
rt300@24 264 }
rt300@24 265 //--------------------------------------------------------------
rt300@24 266 void testApp::lockSynthPressed(bool locked){
rt300@24 267 theGridView.shiftCentreToSnapped();
rt300@24 268 yLocked = locked;
rt300@25 269 eventLogger.logEvent(SYNTH_LOCKED);
rt300@24 270
rt300@24 271 }
rt300@24 272 //--------------------------------------------------------------
rt300@24 273 void testApp::seqStartStop(bool go){
rt300@24 274 if(!go){ //stop
rt300@24 275 core.pd.startMessage();
rt300@24 276 core.pd.addFloat(0);
rt300@24 277 core.pd.finishMessage("fromOF", "seqStartStop");
rt300@25 278 eventLogger.logEvent(PAUSE_PRESSED);
rt300@24 279 }else { // play
rt300@24 280 //stopSequencer();
rt300@24 281 core.pd.startMessage();
rt300@24 282 core.pd.addFloat(1);
rt300@24 283 core.pd.finishMessage("fromOF", "seqStartStop");
rt300@25 284 eventLogger.logEvent(PLAY_PRESSED);
rt300@24 285 }
rt300@24 286 }
rt300@24 287 //--------------------------------------------------------------
rt300@24 288 void testApp::showQuestionnaire(){
rt300@24 289 // stop updating / drawing
rt300@37 290
rt300@24 291 // if(eventLogger.questionnaireCompleted) return;
rt300@37 292
rt300@27 293 [topButtonViewController pausePressed:(id)this];
rt300@24 294
rt300@24 295 //stopSequencer
rt300@27 296 seqStartStop(false);
rt300@24 297
rt300@24 298 questionnaireViewController = [[QuestionnaireViewController alloc] initWithNibName:@"QuestionnaireViewController" bundle:nil];
rt300@24 299 [ofxiPhoneGetGLParentView() addSubview:questionnaireViewController.view];
rt300@24 300
rt300@24 301 [questionnaireViewController setAppRef:(id)this];
rt300@24 302 [questionnaireViewController show:(id)this];
rt300@24 303
rt300@24 304 whichInterfaceShowing = QUESTIONNAIRE;
rt300@24 305
rt300@37 306
rt300@24 307 }
rt300@24 308 //--------------------------------------------------------------
rt300@28 309 void testApp::questionnaireHidden(vector<int> answers, const char* userComments){
rt300@24 310 // send answers to server as json
rt300@28 311 eventLogger.questionnaireAnswersObtained(answers, userComments);
rt300@39 312
rt300@39 313 freeUseMode();
rt300@37 314
rt300@39 315 }
rt300@39 316 //--------------------------------------------------------------
rt300@39 317 // shortcut function for testing
rt300@39 318 void testApp::justStart(){
rt300@39 319 freeUseMode();
rt300@39 320 }
rt300@39 321 //--------------------------------------------------------------
rt300@39 322 void testApp::freeUseMode(){
rt300@38 323 interfaceSelected(1);
rt300@32 324 [bottomTabViewController show:(id)this withSelection:1];
rt300@24 325
rt300@38 326 [topButtonViewController enableSmoothSwitch:(id)this];
rt300@37 327
rt300@39 328 sendMIDIAndOSC = true;
rt300@38 329 }
rt300@38 330 //--------------------------------------------------------------
rt300@38 331 void testApp::setInterp(int state){
rt300@38 332 if(state == 0){
rt300@38 333 theGridView.setInterpolation(Grid::NO_INTERPOLATION);
rt300@39 334 eventLogger.logEvent(SMOOTHING_OFF);
rt300@38 335 }else if(state == 1){
rt300@38 336 theGridView.setInterpolation(Grid::INTERPOLATE_GRID);
rt300@39 337 eventLogger.logEvent(SMOOTHING_ON);
rt300@38 338 }
rt300@38 339 // tell sliders and PD
rt300@38 340 setAllGUISliders(theGridView.getParams());
rt300@39 341
rt300@33 342 }
rt300@33 343 //--------------------------------------------------------------
rt300@24 344 void testApp::showIntro(){
rt300@37 345
rt300@24 346 cout << "SHOW INTRO\n";
rt300@37 347
rt300@29 348 [tsc cancelTimers];
rt300@29 349 bottomTabViewController.view.hidden = YES;
rt300@24 350 introViewController = [[IntroViewController alloc] initWithNibName:@"IntroViewController" bundle:nil];
rt300@24 351 [ofxiPhoneGetGLParentView() addSubview:introViewController.view];
rt300@24 352
rt300@24 353 [introViewController setAppRef:(id)this];
rt300@24 354 [introViewController show:(id)this];
rt300@24 355
rt300@24 356
rt300@24 357 whichInterfaceShowing = INTRO;
rt300@24 358
rt300@24 359 }
rt300@24 360 //--------------------------------------------------------------
rt300@24 361 void testApp::introHidden(bool OK){
rt300@24 362 if(OK){
rt300@25 363 eventLogger.consentGiven = true;
rt300@29 364 //
rt300@29 365 // clear presets?
rt300@29 366 presetManager.clearAll();
rt300@25 367 // show username prompt
rt300@25 368 [usernameAlertViewController showUserNamePrompt];
rt300@32 369 // reset top buttons
rt300@32 370 [topButtonViewController unlockAll];
rt300@32 371 randomise();
rt300@24 372 }
rt300@24 373 // no unOK
rt300@24 374 }
rt300@24 375 //--------------------------------------------------------------
rt300@42 376 void testApp::startTimedSession(){
rt300@42 377 [tsc startTimer];
rt300@42 378 // timer will show alert and set interface
rt300@42 379 }
rt300@42 380 //--------------------------------------------------------------
rt300@39 381 // called from BottomTabViewController iOS segmented thing, also timed session controller
rt300@24 382 void testApp::interfaceSelected(int which){
rt300@24 383 switch (which){
rt300@39 384 case 0: // slider
rt300@43 385 //SLIDER
rt300@24 386 whichInterfaceShowing = SLIDERS;
rt300@43 387
rt300@43 388 [sliderViewController show:(id)this];
rt300@24 389 // set the slider values to stuff got from zoomer
rt300@24 390 sliderVals = theGridView.getParams();
rt300@24 391 setAllGUISliders(sliderVals);
rt300@25 392
rt300@24 393 break;
rt300@39 394 case 1: // both
rt300@43 395 //SLIDER
rt300@24 396 whichInterfaceShowing = BOTH;
rt300@43 397
rt300@43 398 [sliderViewController show:(id)this];
rt300@24 399 // set the slider values to stuff got from zoomer
rt300@24 400 sliderVals = theGridView.getParams();
rt300@24 401 setAllGUISliders(sliderVals);
rt300@39 402
rt300@24 403 break;
rt300@39 404 case 2: // zoomer
rt300@43 405 //SLIDER
rt300@43 406
rt300@43 407 [sliderViewController hide:(id)this];
rt300@24 408 whichInterfaceShowing = ZOOMER;
rt300@24 409 break;
rt300@24 410 }
rt300@39 411 eventLogger.logEvent(SWAP_VIEW,theGridView.getCoord(),theGridView.getScale(), which);
rt300@24 412 }
rt300@24 413 //--------------------------------------------------------------
rt300@24 414 //--------------------------------------------------------------
rt300@24 415 void testApp::setupSliderGui(){
rt300@43 416 //SLIDER not used
rt300@24 417 float length = SLIDER_GUI_WIDTH - (OFX_UI_GLOBAL_WIDGET_SPACING*2);
rt300@24 418
rt300@24 419
rt300@24 420 //float dim = 42;
rt300@24 421
rt300@24 422 // make this iphone size...?
rt300@24 423 int height = 480;
rt300@39 424
rt300@24 425 float dim = (height-10.0*OFX_UI_GLOBAL_WIDGET_SPACING)/10.0;
rt300@24 426 // LEFT GUI
rt300@42 427 sliderGUI = new ofxUICanvas(10,160,SLIDER_GUI_WIDTH,getHeight());
rt300@37 428
rt300@24 429 // Uh.. loop this
rt300@24 430 for(int i = 1; i<=10;i++){
rt300@37 431
rt300@24 432 ofxUISlider *slider;
rt300@25 433 slider = (ofxUISlider *)sliderGUI->addWidgetDown(new ofxUISlider(length,dim,0.0,127,64,sliderParamNames[i-1]));
rt300@24 434 slider->setDrawPadding(true);
rt300@28 435 slider->setDrawPaddingOutline(true);
rt300@24 436 if(i <= 5){
rt300@24 437 slider->setColorFill(ofColor(0,0,255));
rt300@24 438 slider->setColorFillHighlight(ofColor(0,0,255));
rt300@24 439 }else{
rt300@24 440 slider->setColorFill(ofColor(255,0,0));
rt300@24 441 slider->setColorFillHighlight(ofColor(255,0,0));
rt300@24 442 }
rt300@24 443
rt300@24 444 sliders.push_back(slider);
rt300@24 445 }
rt300@24 446
rt300@37 447
rt300@24 448
rt300@24 449 ofAddListener(sliderGUI->newGUIEvent, this, &testApp::sliderGUIEvent);
rt300@37 450
rt300@24 451 }
rt300@24 452 //--------------------------------------------------------------
rt300@24 453 void testApp::sliderGUIEvent(ofxUIEventArgs &e){
rt300@43 454 //SLIDER not used
rt300@24 455 if(whichInterfaceShowing == ZOOMER){
rt300@24 456 cout << "GUI ERROR";
rt300@24 457 return;
rt300@24 458 }
rt300@37 459
rt300@0 460 // "normal" parameter changes
rt300@0 461 for(int i = 1; i<=10;i++){
rt300@0 462
rt300@24 463 if(e.widget->getName() == sliderParamNames[i-1])
rt300@0 464 {
rt300@0 465 //cout << "param change: " << p;
rt300@0 466 ofxUISlider *slider = (ofxUISlider *) e.widget;
rt300@3 467 sliderMoved(i-1,slider->getScaledValue()); // internal array 0 indexed
rt300@0 468 }
rt300@0 469 }
rt300@37 470
rt300@0 471 }
rt300@43 472
rt300@0 473 //--------------------------------------------------------------
rt300@3 474 void testApp::sliderMoved(int which, float value){
rt300@43 475
rt300@3 476 // an update caused by slider view being touched
rt300@0 477 sliderVals[which] = (int)value;
rt300@0 478 theGridView.setParams(sliderVals);
rt300@37 479
rt300@3 480 sendParametersToPD();
rt300@39 481 if(sendMIDIAndOSC){
rt300@39 482
rt300@39 483 sendMidiParam(which);
rt300@39 484 sendOSCParams();
rt300@39 485 }
rt300@5 486
rt300@9 487 eventLogger.logEvent(CHANGE_SLIDER, TwoVector(),0.0,which , value);
rt300@5 488
rt300@0 489 }
rt300@0 490 //--------------------------------------------------------------
rt300@3 491 void testApp::setAllGUISliders(vector<int> vals){
rt300@43 492 //SLIDER
rt300@3 493 // an update caused by zoomer view being moved
rt300@25 494 for(int i = 0; i<NUM_PARAMS;i++){
rt300@0 495 sliders[i]->setValue(vals[i]);
rt300@1 496 sliderVals[i] = vals[i];
rt300@43 497
rt300@43 498 [sliderViewController setSlider:i to:vals[i]];
rt300@0 499 }
rt300@3 500
rt300@39 501 sendParametersToPD();
rt300@39 502 if(sendMIDIAndOSC){
rt300@39 503
rt300@39 504 sendMidiParams();
rt300@39 505 sendOSCParams();
rt300@39 506 }
rt300@39 507
rt300@0 508 }
rt300@0 509 //--------------------------------------------------------------
rt300@25 510 void testApp::randomise(){
rt300@25 511 // pick random settings for all params
rt300@39 512
rt300@39 513 // random zoom? no.
rt300@25 514 for(int i=0; i < NUM_PARAMS ; i++){
rt300@25 515 sliderVals[i] = ofRandom(0, 127);
rt300@25 516
rt300@25 517 }
rt300@37 518 currentSequence = ofRandom(0, sequences.size()-1);
rt300@25 519 // send to grid, sliders and PD
rt300@25 520 theGridView.setParams(sliderVals);
rt300@25 521 setAllGUISliders(sliderVals);
rt300@39 522
rt300@39 523
rt300@25 524 eventLogger.logEvent(RANDOMISE, theGridView.getCoord() ,0.0);
rt300@25 525
rt300@25 526 }
rt300@39 527 //--------------------------------------------------------------
rt300@27 528 void testApp::showHelp(){
rt300@29 529 whichInterfaceShowing = HELP;
rt300@27 530 seqStartStop(false);
rt300@27 531 [topButtonViewController pausePressed:(id)this];
rt300@27 532 helpViewController.view.hidden = NO;
rt300@27 533 eventLogger.logEvent(HELP_PRESSED);
rt300@27 534 }
rt300@27 535 void testApp::helpHidden(){
rt300@29 536 whichInterfaceShowing = BOTH;
rt300@27 537 // start seq?
rt300@27 538
rt300@27 539 }
rt300@25 540 //--------------------------------------------------------------
rt300@36 541 void testApp::nextSequence(){
rt300@36 542 currentSequence++;
rt300@36 543 if(currentSequence >= sequences.size()){
rt300@36 544 currentSequence = 0;
rt300@36 545 }
rt300@36 546 sendParametersToPD();
rt300@36 547 }
rt300@36 548 //--------------------------------------------------------------
rt300@39 549 //--------------------------------------------------------------
rt300@39 550 #pragma mark sending to pd and midi
rt300@3 551 void testApp::sendParametersToPD(){
rt300@37 552 static int previousSequence;
rt300@37 553 // frequencer stuff to get 16 steps
rt300@36 554
rt300@37 555 vector<double> vals;
rt300@37 556
rt300@37 557
rt300@37 558 vals.push_back((sliderVals[0]+32)*8.); // DC offset
rt300@37 559 for(int i=1; i<5;i++){
rt300@37 560 vals.push_back((sliderVals[i] - 64)*2.);
rt300@37 561 }
rt300@37 562
rt300@37 563 vector<double> steps = frequencer.freqMagEdit(freqIndexes, vals);
rt300@37 564 List seqSteps;
rt300@37 565 seqSteps.addSymbol("seqSteps");
rt300@37 566 for(int i=0; i < 16; i++){
rt300@37 567 seqSteps.addFloat(round(steps[i]));
rt300@37 568 }
rt300@37 569 core.pd.sendList("fromOF", seqSteps);
rt300@37 570
rt300@36 571 /*
rt300@37 572 if(currentSequence != previousSequence){
rt300@37 573 List seqSteps;
rt300@37 574
rt300@37 575 seqSteps.addSymbol("seqSteps");
rt300@37 576 if(currentSequence >= sequences.size() || currentSequence < 0){
rt300@37 577 cout << "ERROR: not a valid sequence index\n";
rt300@37 578 for(int i=0; i < 16; i++){
rt300@37 579 seqSteps.addFloat(50);
rt300@37 580 }
rt300@37 581 }else{
rt300@37 582 for(int i=0; i < 16; i++){
rt300@37 583 seqSteps.addFloat(round(sequences[currentSequence][i]));
rt300@37 584 }
rt300@37 585 }
rt300@37 586
rt300@37 587 core.pd.sendList("fromOF", seqSteps);
rt300@37 588 previousSequence = currentSequence;
rt300@3 589 }
rt300@36 590 */
rt300@36 591
rt300@37 592 // send synth params
rt300@3 593 sendOscShape(sliderVals[5]);
rt300@3 594 sendFiltType(sliderVals[6]);
rt300@3 595 sendFiltFreq(sliderVals[7]);
rt300@3 596 sendEnvShape(sliderVals[8]);
rt300@3 597 sendModFreq(sliderVals[9]);
rt300@39 598
rt300@3 599
rt300@3 600 }
rt300@39 601 //--------------------------------------------------------------
rt300@39 602 void testApp::sendMidiParam(int which){
rt300@39 603 int midiChannel = 7;
rt300@39 604 int offset = 0;
rt300@39 605
rt300@39 606 for(int i = 0; i < outputs.size(); ++i) {
rt300@39 607 outputs[i]->sendControlChange(midiChannel, offset+which, sliderVals[which]);
rt300@39 608 }
rt300@39 609
rt300@39 610
rt300@39 611 }
rt300@39 612 //--------------------------------------------------------------
rt300@39 613 void testApp::sendMidiParams(){
rt300@39 614
rt300@39 615 for(int i = 0; i< sliderVals.size(); i++){
rt300@39 616 for(int j = 0; j < outputs.size(); ++j) {
rt300@39 617 outputs[j]->sendControlChange(midiChannel, midiOffset+i, sliderVals[i]);
rt300@39 618 }
rt300@39 619 }
rt300@39 620
rt300@39 621 }
rt300@39 622 //--------------------------------------------------------------
rt300@39 623 void testApp::sendOSCParams(){
rt300@39 624
rt300@39 625 ofxOscMessage m;
rt300@39 626 m.setAddress( "sonicZoom" );
rt300@39 627
rt300@39 628 for(int i = 0; i< sliderVals.size(); i++){
rt300@39 629
rt300@39 630 m.addFloatArg(sliderVals[i]);
rt300@39 631
rt300@39 632 }
rt300@39 633 sender.sendMessage( m );
rt300@39 634 }
rt300@39 635 //--------------------------------------------------------------
rt300@39 636
rt300@27 637 void testApp::setupNewUser(){
rt300@27 638 // this function is for supervised trials with my ipad
rt300@27 639 eventLogger.newUser();
rt300@27 640 }
rt300@8 641 //--------------------------------------------------------------
rt300@3 642 #pragma mark STANDARD OF FUNCTIONS
rt300@3 643 //--------------------------------------------------------------
rt300@0 644 void testApp::update(){
rt300@37 645
rt300@16 646 if(paused) return;
rt300@16 647
rt300@32 648 if(ofxiPhoneExternalDisplay::isExternalScreenConnected()){
rt300@32 649 if(!ofxiPhoneExternalDisplay::isMirroring()){
rt300@32 650 ofxiPhoneExternalDisplay::mirrorOn();
rt300@32 651 printf("turned on Mirroring!\n");
rt300@32 652 }
rt300@32 653 }
rt300@32 654
rt300@27 655 // continiue to move or zoom at velocity, unless snapped
rt300@3 656
rt300@3 657 if (numActiveTouches == 0){ // no touches, use momentum
rt300@32 658 // ZOOM MOMENTUM
rt300@32 659 // continiue to zoom at velocity
rt300@32 660 if (numActiveTouches < 2 && abs(zoomVel)>0.001){
rt300@32 661 theGridView.zoom(zoomVel + 1.0); // +1 because zoomVel factor is + or - , wheras zoom is a multiplier near 1
rt300@32 662 zoomVel = zoomVel*slowFactor;
rt300@32 663 moveVel.setCoord(0.0,0.0);; // don't move if zooming! Too many events!
rt300@35 664
rt300@37 665 setAllGUISliders(theGridView.getParams());
rt300@39 666
rt300@32 667 }
rt300@32 668
rt300@22 669 if(moveVel.norm() > 0.3){
rt300@22 670 if(theGridView.snapped){
rt300@28 671 // stop it (snap check sends snap event)
rt300@22 672 moveVel.setCoord(0.0,0.0);
rt300@22 673 }else{
rt300@22 674 theGridView.move(moveVel);
rt300@22 675 moveVel = moveVel*slowFactor;
rt300@22 676 }
rt300@37 677 // and get new parameter values
rt300@5 678 setAllGUISliders(theGridView.getParams());
rt300@39 679
rt300@22 680 }else if(moveVel.norm() > 0.01){ // and less than 0.3
rt300@3 681 // stop it
rt300@3 682 moveVel.setCoord(0.0,0.0);
rt300@5 683 setAllGUISliders(theGridView.getParams());
rt300@39 684
rt300@5 685 eventLogger.logEvent(SCROLL_STOPPED, theGridView.getCoord() );
rt300@22 686
rt300@3 687 }else{
rt300@3 688 // stopped - do nothing
rt300@3 689 }
rt300@37 690
rt300@0 691 }
rt300@37 692
rt300@0 693 }
rt300@39 694
rt300@0 695 //--------------------------------------------------------------
rt300@39 696
rt300@0 697 void testApp::draw(){
rt300@37 698
rt300@24 699 switch (whichInterfaceShowing){
rt300@24 700 case SLIDERS:
rt300@24 701 break;
rt300@24 702 case ZOOMER:
rt300@24 703 theGridView.draw();
rt300@37 704
rt300@24 705 break;
rt300@24 706 case BOTH:
rt300@33 707
rt300@33 708 theGridView.draw();
rt300@37 709
rt300@24 710 break;
rt300@24 711 case INTRO:
rt300@24 712 break;
rt300@24 713
rt300@24 714 case QUESTIONNAIRE:
rt300@24 715 break;
rt300@24 716
rt300@0 717 }
rt300@4 718
rt300@0 719 }
rt300@0 720
rt300@0 721 //--------------------------------------------------------------
rt300@0 722 void testApp::touchDown(ofTouchEventArgs &touch){
rt300@27 723 // in slider gui area?
rt300@43 724 //SLIDER
rt300@24 725 if(whichInterfaceShowing == SLIDERS){
rt300@24 726 return;
rt300@24 727 }else if (whichInterfaceShowing == BOTH && touch.x < (SLIDER_GUI_WIDTH+10)){
rt300@24 728 return;
rt300@24 729
rt300@24 730 }// otherwise we're good to let the zoomer handle touch
rt300@0 731
rt300@0 732 numActiveTouches++;
rt300@27 733 preventingMovePostScroll = false;
rt300@37 734
rt300@0 735 if(touch.id == 0){
rt300@0 736 touch0.setCoord(touch.x,touch.y);
rt300@0 737 prevTouch0 = touch0;
rt300@32 738 // stop zoom
rt300@32 739 zoomVel = 0.0;
rt300@0 740 }else if(touch.id == 1){
rt300@0 741
rt300@0 742 touch1.setCoord(touch.x,touch.y);
rt300@0 743 prevTouch1 = touch1;
rt300@0 744
rt300@0 745 }
rt300@0 746 if(numActiveTouches == 1){
rt300@0 747 moveVel.setCoord(0.0, 0.0);
rt300@0 748 prevMove.setCoord(0.0, 0.0);
rt300@0 749 prevMove2.setCoord(0.0, 0.0);
rt300@27 750
rt300@0 751 }else if(numActiveTouches == 2){
rt300@0 752 zoomVel = 0.0;
rt300@0 753 prevZoom = 0.0;
rt300@0 754 prevZoom2 = 0.0;
rt300@0 755 double dist = touch1.distanceTo(touch0);
rt300@0 756 prevDist = dist;
rt300@0 757 }
rt300@37 758
rt300@0 759 }
rt300@0 760
rt300@0 761 //--------------------------------------------------------------
rt300@0 762 void testApp::touchMoved(ofTouchEventArgs &touch){
rt300@1 763
rt300@24 764 // TODO check if in gui area!!!
rt300@43 765 //SLIDER
rt300@24 766 if(whichInterfaceShowing == SLIDERS){
rt300@24 767 return;
rt300@24 768 }else if (whichInterfaceShowing == BOTH && touch.x < (SLIDER_GUI_WIDTH+10)){
rt300@24 769 return;
rt300@24 770
rt300@27 771 }
rt300@24 772
rt300@27 773 // otherwise we're good to let the zoomer handle touch
rt300@37 774
rt300@1 775 // which one? keep track of each touch point
rt300@0 776 if(touch.id == 0){
rt300@0 777 touch0.setCoord(touch.x,touch.y);
rt300@0 778
rt300@0 779 }else if(touch.id == 1){
rt300@0 780
rt300@0 781 touch1.setCoord(touch.x,touch.y);
rt300@0 782 }
rt300@37 783
rt300@1 784 if(numActiveTouches == 1){
rt300@27 785 if(preventingMovePostScroll) return;
rt300@1 786 handleScroll();
rt300@0 787 }else if(numActiveTouches == 2){
rt300@1 788 handleZoom();
rt300@0 789
rt300@0 790 }
rt300@0 791 prevTouch0 = touch0;
rt300@37 792
rt300@0 793
rt300@0 794 }
rt300@5 795
rt300@1 796 //--------------------------------------------------------------
rt300@27 797 // handle a finger being dragged
rt300@1 798 void testApp::handleScroll(){
rt300@37 799
rt300@1 800 TwoVector move = touch0 - prevTouch0;
rt300@5 801 if(yLocked){
rt300@5 802 move.y = 0.0;
rt300@5 803 }
rt300@5 804 if(xLocked){
rt300@5 805 move.x = 0.0;
rt300@5 806 }
rt300@37 807
rt300@6 808 // check time since last move - if
rt300@6 809 unsigned int moveTime = ofGetSystemTimeMicros();
rt300@6 810 if(moveTime - lastMoveTime > 100000){
rt300@6 811 moveVel = TwoVector(); // zero
rt300@6 812 }else{
rt300@6 813 moveVel = (move*0.3 + prevMove*0.34 + prevMove2*0.38); // use the time
rt300@6 814
rt300@6 815 }
rt300@6 816 lastMoveTime = moveTime;
rt300@6 817
rt300@37 818
rt300@1 819 prevMove2 = prevMove;
rt300@1 820 prevMove = move;
rt300@1 821
rt300@37 822
rt300@3 823 theGridView.move(move);
rt300@3 824
rt300@3 825 // and get new parameter values
rt300@3 826 setAllGUISliders(theGridView.getParams());
rt300@39 827
rt300@1 828 }
rt300@1 829 //--------------------------------------------------------------
rt300@27 830 // handle pinch movememnt
rt300@1 831 void testApp::handleZoom(){
rt300@1 832 // work out change in difference
rt300@1 833 double dist = touch1.distanceTo(touch0);
rt300@1 834 double zoomFactor = prevDist/dist;
rt300@1 835
rt300@1 836 //TODO check for sensible maximums, e.g. spurious touch data
rt300@1 837 if(zoomFactor > 2.0 || zoomFactor < 0.5){
rt300@1 838 cout << "Zoom too much!!!!" << zoomFactor;
rt300@1 839 zoomFactor = 1.0;
rt300@1 840 }
rt300@1 841
rt300@1 842 zoomVel = (zoomFactor-1)*0.3 + prevZoom*0.34 + prevZoom2*0.38;
rt300@1 843 prevZoom2 = prevZoom;
rt300@1 844 prevZoom = (zoomFactor-1);
rt300@1 845
rt300@1 846 theGridView.zoom(zoomFactor);
rt300@1 847
rt300@1 848 prevDist = dist;
rt300@35 849
rt300@3 850
rt300@37 851 setAllGUISliders(theGridView.getParams());
rt300@39 852
rt300@37 853
rt300@37 854
rt300@1 855 }
rt300@0 856 //--------------------------------------------------------------
rt300@0 857 void testApp::touchUp(ofTouchEventArgs &touch){
rt300@1 858 if(numActiveTouches > 0) numActiveTouches--; // dirty
rt300@27 859 preventingMovePostScroll = false;
rt300@24 860 // TODO check if in gui area!!!
rt300@43 861 //SLIDER
rt300@24 862 if(whichInterfaceShowing == SLIDERS){
rt300@24 863 return;
rt300@24 864 }else if (whichInterfaceShowing == BOTH && touch.x < 256){
rt300@24 865 return;
rt300@1 866
rt300@24 867 }// otherwise we're good to let the zoomer handle touch
rt300@24 868
rt300@37 869
rt300@0 870 // which one?
rt300@0 871 if(touch.id == 0){
rt300@0 872 // tricky situation - we tried to zoom but may have left non-move finger on
rt300@0 873 prevTouch0.setCoord(touch.x,touch.y);
rt300@0 874
rt300@0 875 }else if(touch.id == 1){
rt300@0 876
rt300@37 877
rt300@0 878 prevTouch1.setCoord(0,0);
rt300@6 879
rt300@6 880 }
rt300@6 881 if(numActiveTouches == 0){
rt300@6 882 // check time since last move
rt300@6 883 // check time since last move - if
rt300@6 884 unsigned int moveTime = ofGetSystemTimeMicros();
rt300@6 885 if(moveTime - lastMoveTime > 100000){
rt300@6 886 moveVel = TwoVector(); // zero
rt300@6 887 }else{
rt300@6 888 moveVel = (move*0.3 + prevMove*0.34 + prevMove2*0.38); // use the time
rt300@6 889
rt300@6 890 }
rt300@6 891 lastMoveTime = moveTime;
rt300@27 892 }else if (numActiveTouches == 1){
rt300@27 893 // just zoomed , but now lifted one of the fingers
rt300@27 894 // can be bad if moved so create special mode to stop scroll (special modes bad!)
rt300@27 895 preventingMovePostScroll = true;
rt300@0 896 }
rt300@37 897
rt300@0 898 }
rt300@0 899
rt300@0 900 //--------------------------------------------------------------
rt300@0 901 void testApp::touchDoubleTap(ofTouchEventArgs &touch){
rt300@0 902 // preset?
rt300@25 903
rt300@25 904 /* ballses everything for some reason
rt300@37 905 TwoVector centre = TwoVector(getWidth()*0.5,getHeight()*0.5);
rt300@37 906 // if near centre
rt300@37 907 if((touch.x < centre.x+10) && (touch.x > centre.x-10) && (touch.y < centre.y+10) && (touch.y > centre.y-10)){
rt300@37 908 numActiveTouches = 0; // dirty
rt300@37 909 presetManager.showNameDialog();
rt300@37 910
rt300@37 911 }
rt300@25 912 */
rt300@25 913
rt300@0 914 }
rt300@0 915
rt300@0 916 //--------------------------------------------------------------
rt300@0 917 void testApp::lostFocus(){
rt300@37 918
rt300@0 919 }
rt300@0 920
rt300@0 921 //--------------------------------------------------------------
rt300@0 922 void testApp::gotFocus(){
rt300@37 923
rt300@0 924 }
rt300@0 925
rt300@0 926 //--------------------------------------------------------------
rt300@0 927 void testApp::gotMemoryWarning(){
rt300@37 928
rt300@0 929 }
rt300@0 930
rt300@0 931 //--------------------------------------------------------------
rt300@0 932 void testApp::deviceOrientationChanged(int newOrientation){
rt300@37 933 /*
rt300@37 934 cout << "orientation: " << newOrientation;
rt300@37 935
rt300@37 936 if(newOrientation == 4){
rt300@37 937 ofxiPhoneSetOrientation( OF_ORIENTATION_DEFAULT );
rt300@37 938
rt300@37 939 }else if(newOrientation == 3){
rt300@37 940 ofxiPhoneSetOrientation( OF_ORIENTATION_90_LEFT );
rt300@37 941 }else if(newOrientation == 3){
rt300@37 942 ofxiPhoneSetOrientation( OF_ORIENTATION_90_LEFT );
rt300@37 943 }
rt300@37 944
rt300@37 945
rt300@37 946 [ofxiPhoneGetGLView() updateDimensions];
rt300@37 947 */
rt300@0 948 }
rt300@0 949
rt300@0 950
rt300@0 951 //--------------------------------------------------------------
rt300@0 952 void testApp::touchCancelled(ofTouchEventArgs& args){
rt300@37 953
rt300@0 954 }
rt300@3 955 //---------------------------------------------------------------
rt300@3 956 // AUDIO STUFF
rt300@3 957 //---------------------------------------------------------------
rt300@3 958
rt300@3 959 #pragma mark AUDIO STREAMS
rt300@3 960 //--------------------------------------------------------------
rt300@3 961 void testApp::audioReceived(float * input, int bufferSize, int nChannels) {
rt300@3 962 core.audioReceived(input, bufferSize, nChannels);
rt300@3 963 }
rt300@3 964
rt300@3 965 void testApp::audioRequested(float * output, int bufferSize, int nChannels) {
rt300@3 966 core.audioRequested(output, bufferSize, nChannels);
rt300@3 967 }
rt300@3 968 //---------------------------------------------------------------
rt300@3 969 #pragma mark UTILITIES
rt300@0 970
rt300@0 971 // 5hz cut off
rt300@0 972 const double fB[3] = {0.049489956268677, 0.098979912537354, 0.049489956268677};
rt300@0 973
rt300@0 974 const double fA[3] = {1.000000000000000, -1.279632424997809, 0.477592250072517};
rt300@0 975
rt300@0 976 // 1hz cut off
rt300@0 977 //const double fB[3] = {0.002550535158536, 0.005101070317073, 0.002550535158536};
rt300@0 978
rt300@0 979 //const double fA[3] = {1.000000000000000, -1.852146485395936, 0.862348626030081};
rt300@0 980
rt300@0 981
rt300@0 982 //a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)- a(2)*y(n-1) - ... - a(na+1)*y(n-na)
rt300@0 983 //---------------------------------------------------------------
rt300@0 984 vector<float> testApp::vectorFilter(vector<float> newVec){
rt300@0 985 static vector<float> x0(10,0);
rt300@0 986 static vector<float> x1(10,0);
rt300@0 987 static vector<float> x2(10,0);
rt300@0 988 static vector<float> y0(10,0);
rt300@0 989 static vector<float> y1(10,0);
rt300@0 990 static vector<float> y2(10,0);
rt300@0 991
rt300@0 992 x0 = newVec;
rt300@0 993
rt300@0 994 // this low passes a bunch of params values all at once
rt300@0 995 int sz = newVec.size();
rt300@0 996 for(int i=0; i<sz; i++){
rt300@0 997 y0[i] = fB[0]*x0[i] + fB[1]*x1[i] + fB[2]*x2[i] - fA[1]*y1[i] - fA[2]*y2[i];
rt300@0 998 }
rt300@0 999 // shift
rt300@0 1000 x2 = x1;
rt300@0 1001 x1 = x0;
rt300@0 1002 y2 = y1;
rt300@0 1003 y1 = y0;
rt300@0 1004
rt300@0 1005 return y0;
rt300@2 1006 }
rt300@35 1007 //---------------------------------------------------------------
rt300@24 1008 float ctrlSmoother(float newsamp){
rt300@24 1009 static float x1,x2,y1,y2;
rt300@24 1010 float x0, y0;
rt300@37 1011
rt300@24 1012 x0 = newsamp;
rt300@37 1013
rt300@24 1014 y0 = fB[0]*x0 + fB[1]*x1 + fB[2]*x2 - fA[1]*y1 - fA[2]*y2;
rt300@37 1015
rt300@24 1016 // shift
rt300@24 1017 x2 = x1;
rt300@24 1018 x1 = x0;
rt300@24 1019 y2 = y1;
rt300@24 1020 y1 = y0;
rt300@24 1021
rt300@24 1022 return y0;
rt300@24 1023 }
rt300@8 1024 //---------------------------------------------------------------
rt300@3 1025 void testApp::sendOscShape(int ctrlin){
rt300@35 1026 if(ctrlin < 0 || ctrlin > 127){
rt300@35 1027 cout << "ERROR: bad slider value!";
rt300@35 1028 return;
rt300@35 1029 }
rt300@3 1030
rt300@3 1031 static int numpoints = 5;
rt300@3 1032 static int numcontrols = 5;
rt300@3 1033 //float values[points][controls] =
rt300@3 1034 float ctrlout[numcontrols];
rt300@3 1035 string ctrlName[5] = {"pWidth" , "sqVol", "sawVol", "sineVol", "FMAmt"};
rt300@3 1036 float values[5][5] =
rt300@37 1037 {{0.5, 0., 0., 1., 1.}, // 0
rt300@37 1038 {0.5, 0., 0., 1., 0.}, // 32
rt300@3 1039 {0.5, 0., 1., 0., 0.}, // 64
rt300@3 1040 {0.5, 1., 1., 0., 0.}, // 96
rt300@3 1041 {0.01,1., 1., 0., 0.}}; // 127
rt300@37 1042
rt300@3 1043 float fidx = (numpoints-1)*ctrlin/128.;
rt300@3 1044 int idx = floor(fidx);
rt300@3 1045 float frac = fidx - idx;
rt300@3 1046 for(int i=0; i < numcontrols; i++){
rt300@3 1047 ctrlout[i] = (1 - frac)*values[idx][i] + (frac)*values[idx+1][i];
rt300@3 1048 // send to PD
rt300@3 1049 List toPD;
rt300@3 1050
rt300@3 1051 toPD.addSymbol(ctrlName[i]);
rt300@3 1052 toPD.addFloat(ctrlout[i]); // rounding here??
rt300@37 1053
rt300@3 1054 core.pd.sendList("fromOF", toPD);
rt300@3 1055 //cout << ctrlName[i] << "sending" << ctrlout[i] << "\n";
rt300@3 1056 }
rt300@3 1057
rt300@2 1058 }
rt300@8 1059 //---------------------------------------------------------------
rt300@3 1060 void testApp::sendFiltType(int ctrlin){
rt300@35 1061 if(ctrlin < 0 || ctrlin > 127){
rt300@35 1062 cout << "ERROR: bad slider value!";
rt300@35 1063 return;
rt300@35 1064 }
rt300@3 1065 static int numpoints = 3;
rt300@3 1066 static int numcontrols = 4;
rt300@3 1067 //float values[points][controls] =
rt300@3 1068 float ctrlout[numcontrols];
rt300@3 1069 string ctrlName[4] = {"lpLev" , "bpLev", "hpLev", "reson"};
rt300@3 1070 float values[3][4] =
rt300@37 1071 {{2., 0., 0., 1.}, // 0
rt300@24 1072 {0., 10., 0., 10.}, // 64
rt300@24 1073 {0., 0., 1., 1.}}; // 127
rt300@3 1074
rt300@3 1075 float fidx = (numpoints-1)*ctrlin/128.;
rt300@3 1076 int idx = floor(fidx);
rt300@3 1077 float frac = fidx - idx;
rt300@3 1078 for(int i=0; i < numcontrols; i++){
rt300@3 1079 ctrlout[i] = (1 - frac)*values[idx][i] + (frac)*values[idx+1][i];
rt300@3 1080 // send to PD
rt300@3 1081 List toPD;
rt300@3 1082
rt300@3 1083 toPD.addSymbol(ctrlName[i]);
rt300@3 1084 toPD.addFloat(ctrlout[i]); // rounding here??
rt300@3 1085
rt300@3 1086 core.pd.sendList("fromOF", toPD);
rt300@3 1087 //cout << ctrlName[i] << "sending" << ctrlout[i] << "\n";
rt300@3 1088 }
rt300@2 1089 }
rt300@8 1090 //---------------------------------------------------------------
rt300@3 1091 void testApp::sendFiltFreq(int ctrlin){
rt300@35 1092 if(ctrlin < 0 || ctrlin > 127){
rt300@35 1093 cout << "ERROR: bad slider value!";
rt300@35 1094 return;
rt300@35 1095 }
rt300@24 1096 // smooth this
rt300@24 1097 float fin = ctrlin;
rt300@24 1098 float fout;
rt300@24 1099 fout = (int)ctrlSmoother(fin);
rt300@3 1100 List toPD;
rt300@3 1101
rt300@3 1102 toPD.addSymbol("filtFreq");
rt300@37 1103 toPD.addFloat(fout);
rt300@3 1104
rt300@3 1105 core.pd.sendList("fromOF", toPD);
rt300@3 1106 }
rt300@8 1107 //---------------------------------------------------------------
rt300@3 1108 void testApp::sendEnvShape(int ctrlin){
rt300@35 1109 if(ctrlin < 0 || ctrlin > 127){
rt300@35 1110 cout << "ERROR: bad slider value!";
rt300@35 1111 return;
rt300@35 1112 }
rt300@3 1113 static int numpoints = 5;
rt300@3 1114 static int numcontrols = 3;
rt300@3 1115 //float values[points][controls] =
rt300@3 1116 float ctrlout[numcontrols];
rt300@3 1117 string ctrlName[3] = {"attack" , "decay", "sustain"};
rt300@3 1118 float values[5][3] =
rt300@37 1119 {{0., 0., 0.}, // 0
rt300@3 1120 {0., 0.5, 0.}, // 32
rt300@3 1121 {0.0, 1., 0.8}, // 64
rt300@3 1122 {0.99, 0.3, 0.}, // 96
rt300@3 1123 {0.3, 0.1, 0.}}; // 127
rt300@3 1124
rt300@3 1125 float fidx = (numpoints-1)*ctrlin/128.;
rt300@3 1126 int idx = floor(fidx);
rt300@3 1127 float frac = fidx - idx;
rt300@3 1128 for(int i=0; i < numcontrols; i++){
rt300@3 1129 ctrlout[i] = (1 - frac)*values[idx][i] + (frac)*values[idx+1][i];
rt300@3 1130 // send to PD
rt300@3 1131 List toPD;
rt300@3 1132
rt300@3 1133 toPD.addSymbol(ctrlName[i]);
rt300@3 1134 toPD.addFloat(ctrlout[i]); // rounding here??
rt300@3 1135
rt300@3 1136 core.pd.sendList("fromOF", toPD);
rt300@3 1137 //cout << ctrlName[i] << "sending" << ctrlout[i] << "\n";
rt300@3 1138 }
rt300@3 1139 }
rt300@8 1140 //---------------------------------------------------------------
rt300@43 1141 // alternative envelopes: seperate for amp and filt
rt300@43 1142 void testApp::sendAmpEnvShape(int ctrlin){
rt300@43 1143 if(ctrlin < 0 || ctrlin > 127){
rt300@43 1144 cout << "ERROR: bad slider value!";
rt300@43 1145 return;
rt300@43 1146 }
rt300@43 1147 static int numpoints = 5;
rt300@43 1148 static int numcontrols = 3;
rt300@43 1149 //float values[points][controls] =
rt300@43 1150 float ctrlout[numcontrols];
rt300@43 1151 string ctrlName[3] = {"attack" , "decay", "sustain"};
rt300@43 1152 float values[5][3] =
rt300@43 1153 {{0., 0., 0.}, // 0
rt300@43 1154 {0., 0.5, 0.}, // 32
rt300@43 1155 {0.0, 1., 0.8}, // 64
rt300@43 1156 {0.99, 0.3, 0.}, // 96
rt300@43 1157 {0.3, 0.1, 0.}}; // 127
rt300@43 1158
rt300@43 1159 float fidx = (numpoints-1)*ctrlin/128.;
rt300@43 1160 int idx = floor(fidx);
rt300@43 1161 float frac = fidx - idx;
rt300@43 1162 for(int i=0; i < numcontrols; i++){
rt300@43 1163 ctrlout[i] = (1 - frac)*values[idx][i] + (frac)*values[idx+1][i];
rt300@43 1164 // send to PD
rt300@43 1165 List toPD;
rt300@43 1166 toPD.addSymbol("aenv");
rt300@43 1167 toPD.addSymbol(ctrlName[i]);
rt300@43 1168 toPD.addFloat(ctrlout[i]); // rounding here??
rt300@43 1169
rt300@43 1170 core.pd.sendList("fromOF", toPD);
rt300@43 1171 //cout << ctrlName[i] << "sending" << ctrlout[i] << "\n";
rt300@43 1172 }
rt300@43 1173 }
rt300@43 1174 //---------------------------------------------------------------
rt300@43 1175 void testApp::sendFiltEnvShape(int ctrlin){
rt300@43 1176 if(ctrlin < 0 || ctrlin > 127){
rt300@43 1177 cout << "ERROR: bad slider value!";
rt300@43 1178 return;
rt300@43 1179 }
rt300@43 1180 static int numpoints = 5;
rt300@43 1181 static int numcontrols = 3;
rt300@43 1182 //float values[points][controls] =
rt300@43 1183 float ctrlout[numcontrols];
rt300@43 1184 string ctrlName[3] = {"attack" , "decay", "sustain"};
rt300@43 1185 float values[5][3] =
rt300@43 1186 {{0., 0., 0.}, // 0
rt300@43 1187 {0., 0.5, 0.}, // 32
rt300@43 1188 {0.0, 1., 0.8}, // 64
rt300@43 1189 {0.99, 0.3, 0.}, // 96
rt300@43 1190 {0.3, 0.1, 0.}}; // 127
rt300@43 1191
rt300@43 1192 float fidx = (numpoints-1)*ctrlin/128.;
rt300@43 1193 int idx = floor(fidx);
rt300@43 1194 float frac = fidx - idx;
rt300@43 1195 for(int i=0; i < numcontrols; i++){
rt300@43 1196 ctrlout[i] = (1 - frac)*values[idx][i] + (frac)*values[idx+1][i];
rt300@43 1197 // send to PD
rt300@43 1198 List toPD;
rt300@43 1199 toPD.addSymbol("fenv");
rt300@43 1200 toPD.addSymbol(ctrlName[i]);
rt300@43 1201 toPD.addFloat(ctrlout[i]); // rounding here??
rt300@43 1202
rt300@43 1203 core.pd.sendList("fromOF", toPD);
rt300@43 1204 //cout << ctrlName[i] << "sending" << ctrlout[i] << "\n";
rt300@43 1205 }
rt300@43 1206 }
rt300@43 1207 //---------------------------------------------------------------
rt300@3 1208 void testApp::sendModFreq(int ctrlin){
rt300@35 1209 if(ctrlin < 0 || ctrlin > 127){
rt300@35 1210 cout << "ERROR: bad slider value!";
rt300@35 1211 return;
rt300@35 1212 }
rt300@3 1213 float fm = ctrlin/127.;
rt300@3 1214 List toPD;
rt300@3 1215
rt300@3 1216 toPD.addSymbol("FMFreq");
rt300@3 1217 toPD.addFloat(fm); // rounding here??
rt300@3 1218
rt300@3 1219 core.pd.sendList("fromOF", toPD);
rt300@8 1220 }
rt300@35 1221 //---------------------------------------------------------------
rt300@35 1222
rt300@35 1223
rt300@35 1224
rt300@35 1225 //---------------------------------------------------------------------------
rt300@35 1226 void saveSequences(){
rt300@35 1227 ofFile sequenceFile(ofxiPhoneGetDocumentsDirectory() + "pilot_sequences.json" ,ofFile::WriteOnly);
rt300@35 1228
rt300@35 1229 // the 5 harmonics for the frequencer
rt300@35 1230 vector<int> freqIndexes;
rt300@35 1231 freqIndexes.push_back(0);
rt300@35 1232 freqIndexes.push_back(4);
rt300@35 1233 freqIndexes.push_back(6);
rt300@35 1234 freqIndexes.push_back(7);
rt300@35 1235 freqIndexes.push_back(8);
rt300@35 1236
rt300@35 1237 // loop thru all presets
rt300@35 1238 int N = presetManager.thePresets.size();
rt300@35 1239
rt300@35 1240 vector<int> sliderVals;
rt300@35 1241
rt300@35 1242 Json::Value root;
rt300@35 1243
rt300@35 1244 vector<double> vals;
rt300@35 1245
rt300@35 1246 for(int i = 0; i< N ; i++){
rt300@35 1247 sliderVals = theGridView.calculateParamsFromCoord(presetManager.thePresets[i]->coordinates);
rt300@35 1248
rt300@35 1249 vals.push_back((sliderVals[0]+32)*8.); // DC offset
rt300@35 1250 for(int i=1; i<5;i++){
rt300@35 1251 vals.push_back((sliderVals[i] - 64)*2.);
rt300@35 1252 }
rt300@35 1253
rt300@35 1254
rt300@35 1255 vector<double> steps = frequencer.freqMagEdit(freqIndexes, vals);
rt300@35 1256
rt300@35 1257 for(int j = 0; j<16;j++){
rt300@35 1258 root["sequences"][i][j] = int(steps[j]);
rt300@35 1259 }
rt300@35 1260 vals.clear();
rt300@35 1261 }
rt300@35 1262
rt300@35 1263 //cout << root;
rt300@35 1264 sequenceFile << root;
rt300@35 1265 }
rt300@35 1266 //=--------------------------------------------------------------------
rt300@36 1267 void testApp::loadSequences(){
rt300@36 1268
rt300@36 1269 // read in sequence preset file
rt300@36 1270 string jsonFile = ofxiPhoneGetDocumentsDirectory() + "pilot_sequences.json";
rt300@37 1271
rt300@36 1272 Json::Value root;
rt300@36 1273 Json::Reader reader;
rt300@37 1274
rt300@36 1275 ifstream theFile(jsonFile.c_str());
rt300@36 1276 stringstream fileText;
rt300@36 1277 string line;
rt300@36 1278 if(!theFile){
rt300@36 1279 cout<<"can't find sequence file: " << jsonFile.c_str() << "\n";
rt300@36 1280 return;
rt300@36 1281 }else{
rt300@36 1282
rt300@36 1283 while(theFile){
rt300@36 1284 theFile >> line;
rt300@36 1285 // cout << line << "\n"; // lots?
rt300@37 1286 fileText << line;
rt300@36 1287 }
rt300@36 1288
rt300@36 1289 theFile.close();
rt300@36 1290 }
rt300@36 1291
rt300@36 1292 bool parsingSuccessful = reader.parse( fileText.str(), root );
rt300@36 1293
rt300@36 1294 if ( !parsingSuccessful )
rt300@36 1295 {
rt300@36 1296 // report to the user the failure and their locations in the document.
rt300@36 1297 std::cout << "Failed to parse sequence JSON: \n"
rt300@36 1298 << reader.getFormattedErrorMessages();
rt300@36 1299 return;
rt300@36 1300 }
rt300@36 1301
rt300@36 1302 // now put into variables
rt300@36 1303 const Json::Value jseqs = root["sequences"];
rt300@36 1304 int N = jseqs.size();
rt300@36 1305 for(int i=0; i<N; i++){
rt300@36 1306 sequences.push_back(vector<int>());
rt300@36 1307 for(int j=0; j<jseqs[i].size(); j++){
rt300@36 1308 sequences.back().push_back(jseqs[i][j].asInt());
rt300@36 1309 }
rt300@36 1310 }
rt300@36 1311 // currentSequence
rt300@37 1312
rt300@37 1313 currentSequence = ofRandom(0,N-1);
rt300@36 1314
rt300@36 1315 }
rt300@39 1316 //-------------------------------------------------------------------------
rt300@39 1317 //--------------------------------------------------------------
rt300@39 1318
rt300@39 1319 #pragma mark MIDI
rt300@39 1320 void testApp::addMessage(string msg) {
rt300@39 1321 cout << msg << endl;
rt300@39 1322 messages.push_back(msg);
rt300@39 1323 while(messages.size() > maxMessages)
rt300@39 1324 messages.pop_front();
rt300@39 1325 }
rt300@39 1326
rt300@39 1327 //--------------------------------------------------------------
rt300@39 1328 void testApp::newMidiMessage(ofxMidiMessage& msg) {
rt300@39 1329 //addMessage(msg.toString());
rt300@39 1330
rt300@39 1331 // look at what it is
rt300@39 1332
rt300@39 1333 if(msg.channel == midiChannel && msg.status == MIDI_CONTROL_CHANGE){
rt300@39 1334 int ctl_num = msg.control;
rt300@39 1335 int ctl_val = msg.value;
rt300@39 1336 if(ctl_num - midiOffset >= 0 && ctl_num - midiOffset < sliderVals.size()){
rt300@39 1337 sliderVals[ctl_num] = (int)ctl_val;
rt300@39 1338 sliders[ctl_num]->setValue(ctl_val);
rt300@39 1339 theGridView.setParams(sliderVals);
rt300@39 1340 }
rt300@39 1341 }
rt300@39 1342
rt300@39 1343 }
rt300@39 1344
rt300@39 1345 //--------------------------------------------------------------
rt300@39 1346 void testApp::midiInputAdded(string name, bool isNetwork) {
rt300@39 1347 stringstream msg;
rt300@39 1348 msg << "ofxMidi: input added: " << name << " network: " << isNetwork;
rt300@39 1349 cout << msg.str();
rt300@39 1350 addMessage(msg.str());
rt300@39 1351
rt300@39 1352 // create and open a new input port
rt300@39 1353 ofxMidiIn * newInput = new ofxMidiIn;
rt300@39 1354 newInput->openPort(name);
rt300@39 1355 newInput->addListener(this);
rt300@39 1356 inputs.push_back(newInput);
rt300@39 1357 }
rt300@39 1358
rt300@39 1359 //--------------------------------------------------------------
rt300@39 1360 void testApp::midiInputRemoved(string name, bool isNetwork) {
rt300@39 1361 stringstream msg;
rt300@39 1362 msg << "ofxMidi: input removed: " << name << " network: " << isNetwork << endl;
rt300@39 1363 cout << msg.str();
rt300@39 1364 addMessage(msg.str());
rt300@39 1365
rt300@39 1366 // close and remove input port
rt300@39 1367 vector<ofxMidiIn*>::iterator iter;
rt300@39 1368 for(iter = inputs.begin(); iter != inputs.end(); ++iter) {
rt300@39 1369 ofxMidiIn * input = (*iter);
rt300@39 1370 if(input->getName() == name) {
rt300@39 1371 input->closePort();
rt300@39 1372 input->removeListener(this);
rt300@39 1373 delete input;
rt300@39 1374 inputs.erase(iter);
rt300@39 1375 break;
rt300@39 1376 }
rt300@39 1377 }
rt300@39 1378 }
rt300@39 1379
rt300@39 1380 //--------------------------------------------------------------
rt300@39 1381 void testApp::midiOutputAdded(string name, bool isNetwork) {
rt300@39 1382 stringstream msg;
rt300@39 1383 msg << "ofxMidi: output added: " << name << " network: " << isNetwork << endl;
rt300@39 1384 cout << msg.str();
rt300@39 1385 addMessage(msg.str());
rt300@39 1386
rt300@39 1387 // create and open new output port
rt300@39 1388 ofxMidiOut * newOutput = new ofxMidiOut;
rt300@39 1389 newOutput->openPort(name);
rt300@39 1390 outputs.push_back(newOutput);
rt300@39 1391 }
rt300@39 1392
rt300@39 1393 //--------------------------------------------------------------
rt300@39 1394 void testApp::midiOutputRemoved(string name, bool isNetwork) {
rt300@39 1395 stringstream msg;
rt300@39 1396 msg << "ofxMidi: output removed: " << name << " network: " << isNetwork << endl;
rt300@39 1397 cout << msg.str();
rt300@39 1398 addMessage(msg.str());
rt300@39 1399
rt300@39 1400 // close and remove output port
rt300@39 1401 vector<ofxMidiOut*>::iterator iter;
rt300@39 1402 for(iter = outputs.begin(); iter != outputs.end(); ++iter) {
rt300@39 1403 ofxMidiOut * output = (*iter);
rt300@39 1404 if(output->getName() == name) {
rt300@39 1405 output->closePort();
rt300@39 1406 delete output;
rt300@39 1407 outputs.erase(iter);
rt300@39 1408 break;
rt300@39 1409 }
rt300@39 1410 }
rt300@39 1411 }
rt300@39 1412 //--------------------------------------------------------------