diff testApp.mm @ 39:df7c08faf541

MIDI, small improvements.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Thu, 11 Apr 2013 16:56:21 +0100
parents 0dfe9e0c01aa
children af06bb942d58
line wrap: on
line diff
--- a/testApp.mm	Wed Apr 10 18:57:05 2013 +0100
+++ b/testApp.mm	Thu Apr 11 16:56:21 2013 +0100
@@ -1,7 +1,6 @@
 #include "testApp.h"
 
-#define SLIDER_GUI_WIDTH 256
-#define NUM_PARAMS 10
+
 extern Grid theGridView;
 extern PresetManager presetManager;
 extern EventLogger eventLogger;
@@ -19,12 +18,12 @@
 //--------------------------------------------------------------
 void testApp::setup(){
     paused = true;
-    
+    sendMIDIAndOSC = false;
     
     ofBackground( 0, 0, 0 );
     ofEnableAlphaBlending();
     currentSequence = 0;
-    //ofEnableSmoothing();
+    ofEnableSmoothing();
     
 	// open an outgoing connection to HOST:PORT for OSC
     
@@ -137,6 +136,53 @@
     
     //[sliderViewController show:(id)this];
     
+    /////////////////////////
+    // MIDI
+    
+    midiChannel = 7;
+    midiOffset = 0;
+	
+	// enables the network midi session between iOS and Mac OSX on a
+	// local wifi network
+	//
+	// in ofxMidi: open the input/outport network ports named "Session 1"
+	//
+	// on OSX: use the Audio MIDI Setup Utility to connect to the iOS device
+	//
+	ofxMidi::enableNetworking();
+	
+	// list the number of available input & output ports
+	ofxMidiIn::listPorts();
+	ofxMidiOut::listPorts();
+	
+	// create and open input ports
+	for(int i = 0; i < ofxMidiIn::getNumPorts(); ++i) {
+		
+		// new object
+		inputs.push_back(new ofxMidiIn);
+		
+		// set this class to receive incoming midi events
+		inputs[i]->addListener(this);
+		
+		// open input port via port number
+		inputs[i]->openPort(i);
+	}
+	
+	// create and open output ports
+	for(int i = 0; i < ofxMidiOut::getNumPorts(); ++i) {
+		
+		// new object
+		outputs.push_back(new ofxMidiOut);
+		
+		// open input port via port number
+		outputs[i]->openPort(i);
+	}
+	
+	// set this class to receieve midi device (dis)connection events
+	ofxMidi::setConnectionListener(this);
+    
+    // END MIDI
+    
 }
 
 
@@ -153,6 +199,18 @@
     //[topButtonViewController release];
     //[bottomTabViewController release];
     
+    // clean up MIDI
+	for(int i = 0; i < inputs.size(); ++i) {
+		inputs[i]->closePort();
+		inputs[i]->removeListener(this);
+		delete inputs[i];
+	}
+    
+	for(int i = 0; i < outputs.size(); ++i) {
+		outputs[i]->closePort();
+		delete outputs[i];
+	}
+    
     delete sliderGUI;
     
     cout << "exit done \n";
@@ -178,7 +236,7 @@
 void testApp::lockSequencerPressed(bool locked){
     theGridView.shiftCentreToSnapped();
     xLocked = locked;
-    eventLogger.logEvent(SEQ_LOCKED);
+    eventLogger.logEvent(SEQ_LOCKED); // TODO whatabout unlock?
     
     
 }
@@ -229,31 +287,36 @@
 void testApp::questionnaireHidden(vector<int> answers, const char* userComments){
     // send answers to server as json
     eventLogger.questionnaireAnswersObtained(answers, userComments);
+
+    freeUseMode();
     
-    // tell bottomtabviewcontroller to show and select both interface
+}
+//--------------------------------------------------------------
+// shortcut function for testing
+void testApp::justStart(){
+    freeUseMode();
+}
+//--------------------------------------------------------------
+void testApp::freeUseMode(){
     interfaceSelected(1);
     [bottomTabViewController show:(id)this withSelection:1];
     
     [topButtonViewController enableSmoothSwitch:(id)this];
     
-}
-//--------------------------------------------------------------
-// shortcut function for testing
-void testApp::justStart(){
-    interfaceSelected(1);
-    [bottomTabViewController show:(id)this withSelection:1];
-    [topButtonViewController enableSmoothSwitch:(id)this];
+    sendMIDIAndOSC = true;
 }
 //--------------------------------------------------------------
 void testApp::setInterp(int state){
     if(state == 0){
         theGridView.setInterpolation(Grid::NO_INTERPOLATION);
+        eventLogger.logEvent(SMOOTHING_OFF);
     }else if(state == 1){
         theGridView.setInterpolation(Grid::INTERPOLATE_GRID);
+        eventLogger.logEvent(SMOOTHING_ON);
     }
     // tell sliders and PD
     setAllGUISliders(theGridView.getParams());
-    sendParametersToPD();
+    
 }
 //--------------------------------------------------------------
 void testApp::showIntro(){
@@ -288,10 +351,10 @@
     // no unOK
 }
 //--------------------------------------------------------------
-// called from BottomTabViewController iOS segmented thing
+// called from BottomTabViewController iOS segmented thing, also timed session controller
 void testApp::interfaceSelected(int which){
     switch (which){
-        case 0:
+        case 0: // slider
             
             whichInterfaceShowing = SLIDERS;
             sliderGUI->setVisible(true);
@@ -300,26 +363,27 @@
             setAllGUISliders(sliderVals);
             
             break;
-        case 1:
+        case 1: // both
             
             whichInterfaceShowing = BOTH;
             sliderGUI->setVisible(true);
             // set the slider values to stuff got from zoomer
             sliderVals = theGridView.getParams();
             setAllGUISliders(sliderVals);
+            
             break;
-        case 2:
+        case 2: // zoomer
             
             sliderGUI->setVisible(false);
             whichInterfaceShowing = ZOOMER;
             break;
     }
-    eventLogger.logEvent(SWAP_VIEW,TwoVector(),0.0, which);
+    eventLogger.logEvent(SWAP_VIEW,theGridView.getCoord(),theGridView.getScale(), which);
 }
 //--------------------------------------------------------------
 //--------------------------------------------------------------
 void testApp::setupSliderGui(){
-    float xInit = OFX_UI_GLOBAL_WIDGET_SPACING;
+
     float length = SLIDER_GUI_WIDTH - (OFX_UI_GLOBAL_WIDGET_SPACING*2);
     
     
@@ -327,7 +391,7 @@
     
     // make this iphone size...?
     int height = 480;
-    int width = 320;
+
     float dim = (height-10.0*OFX_UI_GLOBAL_WIDGET_SPACING)/10.0;
     // LEFT GUI
     sliderGUI = new ofxUICanvas(0,160,SLIDER_GUI_WIDTH,getHeight());
@@ -381,6 +445,11 @@
     theGridView.setParams(sliderVals);
     
     sendParametersToPD();
+    if(sendMIDIAndOSC){
+        
+        sendMidiParam(which);
+        sendOSCParams();
+    }
     
     eventLogger.logEvent(CHANGE_SLIDER, TwoVector(),0.0,which , value);
     
@@ -393,10 +462,19 @@
         sliderVals[i] = vals[i];
     }
     
+    sendParametersToPD();
+    if(sendMIDIAndOSC){
+        
+        sendMidiParams();
+        sendOSCParams();
+    }
+    
 }
 //--------------------------------------------------------------
 void testApp::randomise(){
     // pick random settings for all params
+    
+    // random zoom? no.
     for(int i=0; i < NUM_PARAMS ; i++){
         sliderVals[i] = ofRandom(0, 127);
         
@@ -405,12 +483,12 @@
     // send to grid, sliders and PD
     theGridView.setParams(sliderVals);
     setAllGUISliders(sliderVals);
-    sendParametersToPD();
-    
+
+
     eventLogger.logEvent(RANDOMISE, theGridView.getCoord() ,0.0);
     
 }
-//-
+//--------------------------------------------------------------
 void testApp::showHelp(){
     whichInterfaceShowing = HELP;
     seqStartStop(false);
@@ -432,6 +510,8 @@
     sendParametersToPD();
 }
 //--------------------------------------------------------------
+//--------------------------------------------------------------
+#pragma mark sending to pd and midi
 void testApp::sendParametersToPD(){
     static int previousSequence;
     // frequencer stuff to get 16 steps
@@ -479,8 +559,45 @@
     sendFiltFreq(sliderVals[7]);
     sendEnvShape(sliderVals[8]);
     sendModFreq(sliderVals[9]);
+
     
 }
+//--------------------------------------------------------------
+void testApp::sendMidiParam(int which){
+    int midiChannel = 7;
+    int offset = 0;
+    
+    for(int i = 0; i < outputs.size(); ++i) {
+        outputs[i]->sendControlChange(midiChannel, offset+which, sliderVals[which]);
+    }
+    
+    
+}
+//--------------------------------------------------------------
+void testApp::sendMidiParams(){
+
+    for(int i = 0; i< sliderVals.size(); i++){
+       	for(int j = 0; j < outputs.size(); ++j) {
+            outputs[j]->sendControlChange(midiChannel, midiOffset+i, sliderVals[i]);
+        }
+    }
+
+}
+//--------------------------------------------------------------
+void testApp::sendOSCParams(){
+       
+    ofxOscMessage m;
+    m.setAddress( "sonicZoom" );
+    
+    for(int i = 0; i< sliderVals.size(); i++){
+        
+        m.addFloatArg(sliderVals[i]);
+        
+    }
+    sender.sendMessage( m );
+}
+//--------------------------------------------------------------
+
 void testApp::setupNewUser(){
     // this function is for supervised trials with my ipad
     eventLogger.newUser();
@@ -510,7 +627,7 @@
             moveVel.setCoord(0.0,0.0);; // don't move if zooming! Too many events!
             
             setAllGUISliders(theGridView.getParams());
-            sendParametersToPD();
+
         }
         
         if(moveVel.norm() > 0.3){
@@ -523,12 +640,12 @@
             }
             // and get new parameter values
             setAllGUISliders(theGridView.getParams());
-            sendParametersToPD();
+
         }else if(moveVel.norm() > 0.01){ // and less than 0.3
             // stop it
             moveVel.setCoord(0.0,0.0);
             setAllGUISliders(theGridView.getParams());
-            sendParametersToPD();
+
             eventLogger.logEvent(SCROLL_STOPPED, theGridView.getCoord() );
             
         }else{
@@ -538,23 +655,9 @@
     }
     
 }
+
 //--------------------------------------------------------------
-void testApp::sendOSCParams(){
-    
-    vector<int> params = theGridView.getParams(); // FILTER HERE? NEED FLOATS...
-    vector<int>::iterator iter = params.begin();
-    
-    ofxOscMessage m;
-    m.setAddress( "p" );
-    
-    for(;iter < params.end();iter++){
-        
-        m.addFloatArg( *iter );
-        
-    }
-    sender.sendMessage( m );
-}
-//--------------------------------------------------------------
+
 void testApp::draw(){
     
     switch (whichInterfaceShowing){
@@ -683,7 +786,7 @@
     
     // and get new parameter values
     setAllGUISliders(theGridView.getParams());
-    sendParametersToPD();
+
 }
 //--------------------------------------------------------------
 // handle pinch movememnt
@@ -708,7 +811,7 @@
     
 
     setAllGUISliders(theGridView.getParams());
-    sendParametersToPD();
+    
 
     
 }
@@ -1104,3 +1207,100 @@
     currentSequence = ofRandom(0,N-1);
     
 }
+//-------------------------------------------------------------------------
+//--------------------------------------------------------------
+
+#pragma mark MIDI
+void testApp::addMessage(string msg) {
+	cout << msg << endl;
+	messages.push_back(msg);
+	while(messages.size() > maxMessages)
+		messages.pop_front();
+}
+
+//--------------------------------------------------------------
+void testApp::newMidiMessage(ofxMidiMessage& msg) {
+	//addMessage(msg.toString());
+    
+    // look at what it is
+
+    if(msg.channel == midiChannel && msg.status == MIDI_CONTROL_CHANGE){
+        int ctl_num = msg.control;
+        int ctl_val = msg.value;
+        if(ctl_num - midiOffset >= 0 && ctl_num - midiOffset < sliderVals.size()){
+            sliderVals[ctl_num] = (int)ctl_val;
+            sliders[ctl_num]->setValue(ctl_val);
+            theGridView.setParams(sliderVals);
+        }
+    }
+ 
+}
+
+//--------------------------------------------------------------
+void testApp::midiInputAdded(string name, bool isNetwork) {
+	stringstream msg;
+	msg << "ofxMidi: input added: " << name << " network: " << isNetwork;
+    cout << msg.str();
+	addMessage(msg.str());
+	
+	// create and open a new input port
+	ofxMidiIn * newInput = new ofxMidiIn;
+	newInput->openPort(name);
+	newInput->addListener(this);
+	inputs.push_back(newInput);
+}
+
+//--------------------------------------------------------------
+void testApp::midiInputRemoved(string name, bool isNetwork) {
+	stringstream msg;
+	msg << "ofxMidi: input removed: " << name << " network: " << isNetwork << endl;
+    cout << msg.str();
+	addMessage(msg.str());
+	
+	// close and remove input port
+	vector<ofxMidiIn*>::iterator iter;
+	for(iter = inputs.begin(); iter != inputs.end(); ++iter) {
+		ofxMidiIn * input = (*iter);
+		if(input->getName() == name) {
+			input->closePort();
+			input->removeListener(this);
+			delete input;
+			inputs.erase(iter);
+			break;
+		}
+	}
+}
+
+//--------------------------------------------------------------
+void testApp::midiOutputAdded(string name, bool isNetwork) {
+	stringstream msg;
+	msg << "ofxMidi: output added: " << name << " network: " << isNetwork << endl;
+    cout << msg.str();
+	addMessage(msg.str());
+	
+	// create and open new output port
+	ofxMidiOut * newOutput = new ofxMidiOut;
+	newOutput->openPort(name);
+	outputs.push_back(newOutput);
+}
+
+//--------------------------------------------------------------
+void testApp::midiOutputRemoved(string name, bool isNetwork) {
+	stringstream msg;
+	msg << "ofxMidi: output removed: " << name << " network: " << isNetwork << endl;
+    cout << msg.str();
+	addMessage(msg.str());
+	
+	// close and remove output port
+	vector<ofxMidiOut*>::iterator iter;
+	for(iter = outputs.begin(); iter != outputs.end(); ++iter) {
+		ofxMidiOut * output = (*iter);
+		if(output->getName() == name) {
+			output->closePort();
+			delete output;
+			outputs.erase(iter);
+			break;
+		}
+	}
+}
+//--------------------------------------------------------------
\ No newline at end of file