diff testApp.mm @ 0:a223551fdc1f

First commit - copy from tweakathlon.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Fri, 10 Oct 2014 11:46:42 +0100
parents
children 851833072cf1
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testApp.mm	Fri Oct 10 11:46:42 2014 +0100
@@ -0,0 +1,734 @@
+#include "testApp.h"
+#include "ofAppiOSWindow.h"
+
+extern EventLogger eventLogger;
+
+// static members inited here. not my choice.
+int SynthParam::mappingUID = 88000;
+//--------------------------------------------------------------
+void testApp::setup(){
+    
+    
+    
+    ofxiPhoneSetOrientation( OF_ORIENTATION_90_LEFT );
+    //ofxiPhoneExternalDisplay::mirrorOn();
+    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
+    // initilaise
+    
+    
+    initialiseVariables();
+    
+    
+    testController = new TestController;
+    
+    messageOrganiser.init(&core, testController);
+    timeController.init();
+    initialiseGUIs();
+    initialiseMIDI();
+    setupUIElements();
+
+
+    
+    light.setSpotlight(45. , 1.);
+    light.enable();
+    ofEnableSeparateSpecularLight();
+    ofEnableDepthTest();
+    ofEnableAlphaBlending();
+    // in setup:
+    myfont.loadFont("NewMedia Fett.ttf", 32);
+    
+    verdBig.loadFont("verdana.ttf", 18, true, true);
+	verdBig.setLineHeight(18.0f);
+	verdBig.setLetterSpacing(1.037);
+
+    //--------------------------------------
+    
+    eventLogger.startLoadAll();
+    //--------------------------------------
+    
+    // now do things that will affect the start up state of the app
+    
+    // initialise PD
+    
+	int ticksPerBuffer = 8;	// 8 * 64 = buffer len of 512
+	core.setup(2, 2, 44100, ticksPerBuffer);
+
+    // setup OF sound stream
+    bufSize = ofxPd::blockSize()*ticksPerBuffer;
+    wavetableNew = (float *) malloc(bufSize * sizeof(float));
+    
+	ofSoundStreamSetup(2, 2, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 3);
+    
+    if(true){ // force start
+        startTheTests();
+    }else{
+        
+        if(eventLogger.questionnaireCompleted){ // then show play again dialog, and log the test number
+            
+        }else{
+            // then we're in timed session mode
+            showIntro();
+        }
+    }
+    paused = false;
+    
+    
+    eventLogger.logEvent(APP_LOADED);
+
+    ofSoundStreamStart();
+
+}
+
+//-----------------------------------------------------------------------------
+
+//DeviceID3523537000
+void testApp::initialiseVariables(){
+    paused = true;
+    ofBackground( 0, 0, 0 );
+    //ofEnableAlphaBlending();
+    //ofEnableSmoothing();
+    
+	// open an outgoing connection to HOST:PORT for OSC
+	// sender.setup( OSC_HOST, OSC_PORT );
+    ofSetFrameRate(60);
+    
+
+}
+//---------------------------------------------------------
+void testApp::initialiseGUIs(){
+
+    // set up iOS gui stuff
+    
+    helpViewController	= [[HelpViewController alloc] initWithNibName:@"HelpViewController" bundle:nil];
+    [ofxiPhoneGetGLParentView() addSubview:helpViewController.view];
+    [helpViewController setAppRef:(__bridge id)this];
+    helpViewController.view.hidden = YES;
+    
+
+    usernameAlertViewController = [[UsernameAlertViewController alloc] init];
+    [usernameAlertViewController setAppRef:(__bridge id)this];
+ 
+}
+
+//--------------------------------------------------------------
+void testApp::setupUIElements(){
+
+    // eventually: sliderpanel, topbuttonpanel, submitbuttonpanel, countdown panel,
+    
+    // --------------------- BUTTONS
+    UIProps p;
+    ofBackground(p.generalBackground);
+
+    ButtonPanel* bottomButtonPanel = new ButtonPanel(1,160+p.sliderPanelHeight,ofGetWidth(),250,p);
+
+    Buttron* playTargetButton = new Buttron(p.buttonWidth*0.2,680, p);
+    playTargetButton->setLabel("Target");
+    messageOrganiser.mapButtonToAction(playTargetButton, TRIGGER_TARGET_ID);
+    bottomButtonPanel->addButton(playTargetButton);
+    messageOrganiser.setTargetButton(playTargetButton);
+
+    Buttron * playCandidateButton = new Buttron(p.buttonWidth*1.4,680, p);
+    playCandidateButton->setLabel("Current");
+    messageOrganiser.mapButtonToAction(playCandidateButton, TRIGGER_CANDIDATE_ID);
+    bottomButtonPanel->addButton(playCandidateButton);
+    
+    
+    // submit button - only one for now
+    Buttron * submitButton = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p);
+    submitButton->setLabel("Submit");
+    messageOrganiser.mapButtonToAction(submitButton, SUBMIT_CANDIDATE);
+    bottomButtonPanel->addButton(submitButton);
+    
+    //  button - just for spacing pruposes
+    Buttron * spacerButton = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p);
+    spacerButton->setLabel("-");
+    messageOrganiser.mapButtonToAction(spacerButton, TRIGGER_CANDIDATE_ID);
+    bottomButtonPanel->addButton(spacerButton);
+    spacerButton->hide();
+    
+    Buttron * spacerButton2 = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p);
+    spacerButton2->setLabel("-");
+    messageOrganiser.mapButtonToAction(spacerButton2, TRIGGER_CANDIDATE_ID);
+    bottomButtonPanel->addButton(spacerButton2);
+    spacerButton2->hide();
+    
+    messageOrganiser.setBottomPanel(bottomButtonPanel);
+    UIElements.push_back(bottomButtonPanel);
+    bottomButtonPanel->showBorder(false);
+
+
+
+    // ------------------------------------ SLIDERS
+
+    vector<controllerType> sl2;
+    sl2.push_back(SLIDER);
+    
+    SliderPanel * controlPanel = new SliderPanel(1,
+                                                 160,
+                                                 ofGetWidth(),
+                                                 p.sliderPanelHeight,
+                                                 p,
+                                                 sl2);
+    
+    UIElements.push_back(controlPanel);
+    messageOrganiser.setControlPanel(controlPanel);
+    controlPanel->showBorder(true);
+    
+    // -   -   - - - -- -  - OTHER BITS
+    
+    CountdownText * countDownBox = new CountdownText("5" , 500, 380, 455, 455, p);
+    UIElements.push_back(countDownBox);
+    messageOrganiser.setCountdownPanel(countDownBox);
+    countDownBox->hide();
+    
+    TextPanel * scoreFeedback = new TextPanel("Feedback panel", ofGetWidth()*0.5 - p.buttonWidth*0.5, 666, 400,100,p);
+    scoreFeedback->setFontSize(SMALLFONT);
+    UIElements.push_back(scoreFeedback);
+    messageOrganiser.setScorePanel(scoreFeedback);
+    scoreFeedback->hide();
+    
+    TextPanel * finishPanel = new TextPanel("Finish txt panel", 250, 250, 1000,400,p);
+    finishPanel->setFontSize(LARGEFONT);
+    finishPanel->setText("Experiment completed");
+    messageOrganiser.setFinishPanel(finishPanel);
+    
+    UIElements.push_back(finishPanel);
+    finishPanel->hide();
+
+    
+    Buttron * newTestButton = new Buttron(ofGetWidth()-300,690, p);
+    newTestButton->setLabel("Next Test");
+    UIElements.push_back(newTestButton);
+    messageOrganiser.mapButtonToAction(newTestButton, NEW_TEST_ID);
+    newTestButton->hide();
+    messageOrganiser.setNewTestButton(newTestButton);
+    
+    TargetSymbol* targetSymbol = new TargetSymbol(ofGetWidth()*0.5,160,30,p);
+    messageOrganiser.setTargetSymbol(targetSymbol);
+    UIElements.push_back(targetSymbol);
+    
+    // alternation speed
+
+    
+//    ButtronSlider * speedSlider = new ButtronSlider(ofGetWidth()-60, 210, 50, p.sliderHeight/2,FILL, p);
+//    UIElements.push_back(speedSlider);
+//    messageOrganiser.mapButtonToAction(speedSlider, SPEED_CHANGE_ID);
+//    
+//    Buttron * altButton = new Buttron(ofGetWidth()-60, 500, 50, 50,p);
+//    UIElements.push_back(altButton);
+//    altButton->setLabel("Alt");
+//    messageOrganiser.mapButtonToAction(altButton, START_ALTERNATE_ID);
+    
+//    TextPanel * speedLabel = new TextPanel("Speed", ofGetWidth()-55, 195, 50,20,p);
+//    speedLabel->setText("Speed");
+//    speedLabel->setFontSize(SMALLFONT);
+//    speedLabel->show();
+//    UIElements.push_back(speedLabel);
+    
+    // volume
+//    ButtronSlider * volumeSlider = new ButtronSlider(50, 210, 30, p.sliderHeight,FILL, p);
+//    UIElements.push_back(volumeSlider);
+//    messageOrganiser.mapButtonToAction(volumeSlider, VOLUME_CHANGE_ID);
+}
+//--------------------------------------------------------------------------
+void testApp::initialiseMIDI(){
+    
+    /////////////////////////
+    // MIDI
+    
+    midiChannel = 8;
+    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
+
+}
+//--------------------------------------------------------------
+
+template <class T>
+void deleteVectorOfPointers( T * inVectorOfPointers )
+{
+    typename T::iterator i;
+    for ( i = inVectorOfPointers->begin() ; i < inVectorOfPointers->end(); i++ )
+    {
+        delete * i;
+    }
+    //delete inVectorOfPointers;
+}
+
+
+//--------------------------------------------------------------
+void testApp::exit(){
+    eventLogger.logEvent(APP_EXITED);
+    eventLogger.exitAndSave();
+    
+    core.exit();
+    
+    // are these handled automatically?
+    //[introViewController release];
+    //[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];
+	}
+    deleteVectorOfPointers(&UIElements); // TODO this crashes??
+    
+    
+    delete testController;
+    
+    cout << "exit done \n";
+}
+
+#pragma mark GUI
+////////////////////////////
+// These functions called from iOS toolbars
+//--------------------------------------------------------------
+
+//--------------------------------------------------------------
+void testApp::showQuestionnaire(){
+
+    
+    questionnaireViewController	= [[QuestionnaireViewController alloc] initWithNibName:@"QuestionnaireViewController" bundle:nil];
+    [ofxiPhoneGetGLParentView() addSubview:questionnaireViewController.view];
+	
+    [questionnaireViewController setAppRef:(__bridge id)this];
+    [questionnaireViewController show:(__bridge id)this];
+    
+    whichInterfaceShowing = QUESTIONNAIRE;
+    
+    
+}
+//--------------------------------------------------------------
+void testApp::questionnaireHidden(vector<int> answers, const char* userComments){
+    // send answers to server as json
+    eventLogger.questionnaireAnswersObtained(answers, userComments);
+
+}
+
+//--------------------------------------------------------------
+void testApp::showIntro(){
+    
+    cout << "SHOW INTRO\n";
+
+    introViewController	= [[IntroViewController alloc] initWithNibName:@"IntroViewController" bundle:nil];
+    [ofxiPhoneGetGLParentView() addSubview:introViewController.view];
+	
+    [introViewController setAppRef:(__bridge id)this];
+    [introViewController show:(__bridge id)this];
+    
+    whichInterfaceShowing = INTRO;
+    
+}
+//--------------------------------------------------------------
+void testApp::introHidden(){
+    eventLogger.consentGiven = true;
+    eventLogger.logEvent(INTRO_CONSENTED);
+    [usernameAlertViewController showUserNamePrompt];
+    // after prompt goes it calls startTheTests()
+}
+
+//--------------------------------------------------------------
+void testApp::startTheTests(){
+    eventLogger.logEvent(START_THE_TESTS);
+    whichInterfaceShowing = COUNT_DOWN;
+    // do countdown etc
+    messageOrganiser.countdownToNewTest();
+    // TODO how is testApp going to kknow whichInterfaceShowing ???
+    
+}
+//--------------------------------------------------------------
+//--------------------------------------------------------------
+void testApp::showHelp(){
+    // stop clock etc
+    previousInterface = whichInterfaceShowing;
+    whichInterfaceShowing = HELP;
+    helpViewController.view.hidden = NO;
+    eventLogger.logEvent(HELP_PRESSED);
+    
+}
+void testApp::helpHidden(){
+    whichInterfaceShowing = previousInterface;
+    
+}
+//--------------------------------------------------------------
+//--------------------------------------------------------------
+//--------------------------------------------------------------
+#pragma mark sending to pd and midi
+void testApp::sendParametersToPD(){
+
+    
+}
+//--------------------------------------------------------------
+void testApp::sendMidiParam(int which){
+    int midiChannel = 8;
+    int offset = 0;
+    
+    for(int i = 0; i < outputs.size(); ++i) {
+        outputs[i]->sendControlChange(midiChannel, offset+which, 66);
+    }
+    
+    
+}
+
+//--------------------------------------------------------------
+//void testApp::sendOSCParams(){
+//       
+//    ofxOscMessage m;
+//    m.setAddress( "Template" );
+//
+//    m.addFloatArg(9.9999);
+//
+//    sender.sendMessage( m );
+//}
+//--------------------------------------------------------------
+
+void testApp::setupNewUser(){
+    // this function is for supervised trials with my ipad
+    eventLogger.newUser();
+}
+//--------------------------------------------------------------
+#pragma mark STANDARD OF FUNCTIONS
+//--------------------------------------------------------------
+void testApp::update(){
+    
+    if(paused) return;
+    
+    // run timer check here
+    // look at time, work out difference
+    timeController.tick();
+    
+    // test mutex crash thing
+    //eventLogger.logEvent(CANDIDATE_PLAYED);
+}
+//--------------------------------------------------------------
+
+void testApp::appModeChange(interfaceType mode){
+    whichInterfaceShowing = mode;
+}
+
+
+//------------------------------------------------------------------------
+
+void testApp::draw(){
+    
+    switch (whichInterfaceShowing){
+        case QUESTIONNAIRE:
+            break;
+        case INTRO:
+            break;
+        case TEST_IN_PROGRESS:
+            break;
+        case SCORE_AND_HINT:
+            break;
+        case COUNT_DOWN:
+            break;
+        case READY_FOR_NEXT:
+            break;
+        default:
+            break;
+    }
+    
+    
+    
+    drawUIElements();
+    
+    //ofSetColor(234, 234, 234);
+    //ofLine(0,150,1024,150);
+    
+    //drawWaveform();
+    drawScore();
+    
+    
+
+}
+//------------------------------------------------------------------------
+void testApp::drawUIElements(){
+
+    vector<UIElement *>::iterator UIitr;
+    for(UIitr = UIElements.begin(); UIitr < UIElements.end(); UIitr++){
+        (*UIitr)->draw();
+    }
+}
+//------------------------------------------------------------------------
+void testApp::drawScore(){
+    ofColor txtCol = ofColor(150,235,200,255);
+    
+    int score = messageOrganiser.getScore();
+    stringstream msg;
+    
+    msg << "Test: " << testController->getCurrentTestLetter();
+    ofSetColor(txtCol);
+    verdBig.drawString(msg.str(), 40, 140);
+    msg.str(std::string());
+    
+    msg << "Score: " << score;
+    verdBig.drawString(msg.str(), 240, 140);
+    msg.str(std::string());
+    
+    pair<int,int> time;
+    time = messageOrganiser.getTime();
+    msg << "Time taken: " << time.first << ":" << time.second << endl;
+    verdBig.drawString(msg.str(), 600, 140);
+    
+}
+//------------------------------------------------------------------------
+
+//--------------------------------------------------------------
+// passes touch to UI elements
+//--------------------------------------------------------------
+
+void testApp::touchToUIElements(int x, int y, touchType ttype, int tid){
+    vector<UIElement *>::iterator UIitr;
+    for(UIitr = UIElements.begin(); UIitr < UIElements.end(); UIitr++){
+        (*UIitr)->touch(x,y,ttype, tid);
+    }
+}
+
+//--------------------------------------------------------------
+void testApp::touchDown(ofTouchEventArgs &touch){
+    //touch = transformTouchCoords(touch);
+    touchToUIElements(touch.x, touch.y, TOUCH_DOWN, touch.id);
+    
+}
+
+//--------------------------------------------------------------
+void testApp::touchMoved(ofTouchEventArgs &touch){
+
+    touchToUIElements(touch.x, touch.y, TOUCH_MOVED, touch.id);
+    
+}
+
+//--------------------------------------------------------------
+void testApp::touchUp(ofTouchEventArgs &touch){
+
+    touchToUIElements(touch.x, touch.y, TOUCH_UP, touch.id);
+}
+
+
+//--------------------------------------------------------------
+void testApp::touchDoubleTap(ofTouchEventArgs &touch){
+    
+}
+
+//--------------------------------------------------------------
+void testApp::lostFocus(){
+    //exit();
+}
+
+//--------------------------------------------------------------
+void testApp::gotFocus(){
+    
+}
+
+//--------------------------------------------------------------
+void testApp::gotMemoryWarning(){
+    
+}
+
+//--------------------------------------------------------------
+
+void testApp::deviceOrientationChanged(int newOrientation){
+    
+    cout << "orientation: " << newOrientation;
+    
+    // do something here?
+
+}
+
+
+
+//--------------------------------------------------------------
+void testApp::touchCancelled(ofTouchEventArgs& args){
+    
+}
+//---------------------------------------------------------------
+// AUDIO STUFF
+//---------------------------------------------------------------
+
+#pragma mark AUDIO STREAMS
+//--------------------------------------------------------------
+void testApp::audioReceived(float * input, int bufferSize, int nChannels) {
+	//core.audioReceived(input, bufferSize, nChannels);
+}
+
+void testApp::audioRequested(float * output, int bufferSize, int nChannels) {
+
+	core.audioRequested(output, bufferSize, nChannels);
+//    for(int i=0;i<bufferSize/2;i++){
+//        output[i] = 0.2;
+//    }
+//    // pass buffer to drawable thing
+//    for(int i=0;i<bufferSize;i++){
+//        wavetableNew[i] = output[i];
+//    }
+    
+}
+
+void testApp::drawWaveform(){
+    // draw the actual waveform in the corner
+    
+    int width = 768;
+    int height = 128;
+    double sampval = 0.0;
+    int leftsampnum = 0;
+    int rightsampnum = 0;
+    float sampscale = 0.0, prevsampscale = 0.0, interp = 0.0;
+    
+    ofSetColor(256, 0, 0);
+    double step = double(bufSize)/width; // how much we are stepping thru wave per pixel
+    for(int i = 0; i < width; i++){
+        
+        leftsampnum = floor(i * step); // basic nearest neighbour interpolation
+        rightsampnum = ceil(i*step);
+        interp  = (i*step)-leftsampnum;
+        if(rightsampnum < bufSize){
+            sampval = (1 - interp)*wavetableNew[leftsampnum] + interp*wavetableNew[rightsampnum];
+        }
+        sampscale = (sampval * 700) + height/2.0; // centre and scale
+        ofSetLineWidth(2);
+        ofLine(sampscale, i, prevsampscale, i-1); // draw a line from pixel to pixel (?)
+        prevsampscale = sampscale;
+    }
+    
+}
+//---------------------------------------------------------------
+#pragma mark UTILITIES
+//-------------------------------------------------------------------------
+//--------------------------------------------------------------
+
+#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) {
+    
+    // looks out for: 30 31 32 on channel 8
+    if(msg.channel == midiChannel && msg.status == MIDI_CONTROL_CHANGE){
+        int ctl_num = msg.control - 30;
+        int ctl_val = msg.value;
+        // TODO route control change message here
+        //cout << " ctrl : " << ctl_num << " : " << ctl_val << endl;
+        messageOrganiser.midiFromLeap(ctl_num, ctl_val);
+    }
+ 
+}
+
+//--------------------------------------------------------------
+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;
+		}
+	}
+}