hekeus@6: #include "melodyTriangle.h" hekeus@6: #include hekeus@6: samer@15: #define BUFFER_ZONE 80 // have to drag this far to snap out of triange. hekeus@6: /* hekeus@6: /birth id hekeus@6: /death id hekeus@6: /start id hekeus@6: /stop id hekeus@6: /track id x y left right top bottom area hekeus@6: /tempo hekeus@6: hekeus@6: hekeus@6: */ hekeus@8: melodyTriangle::melodyTriangle(const char *host, int port, int numVoices, bool enableKeys,int voiceIdOffset,int receivePort){ hekeus@8: printf("in constructor: %s %i %i %i %i %i\n",host,port,numVoices,enableKeys,voiceIdOffset,receivePort); hekeus@6: this->numVoices=numVoices; hekeus@6: this->enableKeys=enableKeys; hekeus@6: this->voiceIdOffset=voiceIdOffset; hekeus@6: //voices=*Voice[numVoices]; hekeus@6: sender.setup( host,port ); hekeus@8: receiver.setup( receivePort ); hekeus@8: hekeus@6: } hekeus@6: hekeus@6: //-------------------------------------------------------------- hekeus@6: void melodyTriangle::setup(){ hekeus@6: //voices = new Voice[NUMVOICES]; hekeus@6: hekeus@6: ofSetCircleResolution(100); hekeus@6: ofBackground(0,0,0); hekeus@6: ofSetWindowTitle("Melody Triangle"); hekeus@6: triangleHeight=ofGetHeight()*0.75; hekeus@6: ofSetFrameRate(40); // if vertical sync is off, we can go a bit fast... this caps the framerate at 60fps. hekeus@6: ofEnableSmoothing(); hekeus@6: x1=ofGetWidth()/2; hekeus@6: y1=(ofGetHeight()-triangleHeight)/2; hekeus@6: x2=ofGetWidth()/2-triangleHeight/sqrt(3); hekeus@6: y2=ofGetHeight()-(ofGetHeight()-triangleHeight)/2; hekeus@6: x3=ofGetWidth()/2+triangleHeight/sqrt(3); hekeus@6: y3=y2; hekeus@6: samer@15: // used for clipping samer@15: DX13=x3-x1; DY13=y3-y1; samer@15: SQLEN13=DX13*DX13+DY13*DY13; samer@15: samer@12: sendCalibrate(); samer@12: for (int i=0;iy2) { // off the bottom samer@15: clipped=true; samer@15: *y=y2; samer@15: if (*xx3) *x=x3; samer@15: } else { // have to be a bit cleverer samer@15: bool reflect=false; samer@15: if (*x dy*DX13) { samer@15: // (x,y) must be somewhere right of triangle now samer@15: clipped=true; samer@15: int dp=dx*DX13 + dy*DY13; samer@15: if (dp<0) { *x=x1; *y=y1; } // off the top samer@15: else if (dp>SQLEN13) { *x=x3; *y=y3; } // off the bottom right samer@15: else { // project onto right edge samer@15: *x=x1+dp*DX13/SQLEN13; samer@15: *y=y1+dp*DY13/SQLEN13; samer@15: } samer@15: } else { samer@15: clipped=false; hekeus@6: } hekeus@6: samer@15: if (reflect) *x=2*x1 - *x; // reflect back if necessary hekeus@6: } samer@15: return clipped; hekeus@6: } hekeus@6: samer@15: samer@14: void melodyTriangle::sendPosition(Voice v){ hekeus@6: hekeus@6: ofxOscMessage m; hekeus@6: ///track id x y left right top bottom area hekeus@6: m.setAddress( "/track2d" ); hekeus@6: m.addIntArg( v.id ); hekeus@6: m.addIntArg( v.posx ); hekeus@6: m.addIntArg( v.posy ); hekeus@6: sender.sendMessage( m ); hekeus@6: printf("sent - /track2d %i %i %i\n",v.id,v.posx,v.posy); hekeus@6: hekeus@6: } hekeus@6: hekeus@6: //-------------------------------------------------------------- hekeus@6: void melodyTriangle::draw(){ samer@10: bool constrained=false; hekeus@6: bool sendStart=false; samer@15: hekeus@6: if (voiceGrabbed!=-1){ samer@14: Voice *vg=voices[voiceGrabbed]; samer@14: if (mouseX!=vg->posx || mouseY!=vg->posy){ samer@15: int clipx=mouseX, clipy=mouseY; samer@15: bool clipped=clipToTriangle(&clipx,&clipy); samer@15: samer@15: if (vg->inTriangle) { hekeus@6: samer@15: if (clipped) { samer@15: // check how far we clipped samer@15: if (ofDist(clipx, clipy, mouseX, mouseY) > BUFFER_ZONE) { samer@15: // if far enough, we pop out of triangle and send samer@15: // /death samer@15: ofxOscMessage m; samer@15: m.setAddress( "/death" ); samer@15: m.addIntArg( vg->id ); samer@15: sender.sendMessage( m ); hekeus@6: samer@15: printf("sent /death %i \n",vg->id); samer@15: vg->posx=mouseX; samer@15: vg->posy=mouseY; samer@15: vg->inTriangle=false; samer@15: } else { samer@15: // otherwise, we move to clipped point samer@15: constrained=true; samer@15: vg->posx=clipx; samer@15: vg->posy=clipy; samer@15: } samer@15: } else { // not clipped; normal move samer@15: vg->posx=mouseX; samer@15: vg->posy=mouseY; samer@15: } samer@15: } else { // token was outside triangle samer@15: vg->posx=mouseX; samer@15: vg->posy=mouseY; samer@15: if (!clipped){ // ie mouse now in triangle samer@15: //birth id hekeus@7: samer@10: ofxOscMessage m; samer@15: m.setAddress( "/birth" ); samer@14: m.addIntArg( vg->id ); samer@10: sender.sendMessage( m ); samer@15: samer@15: printf("sent /birth %i \n",vg->id); samer@15: sendOctave(vg->id,vg->octave); samer@15: sendAmplitude(vg->id,vg->amplitude); samer@15: sendStart=true; samer@15: vg->inTriangle=true; hekeus@6: } hekeus@6: } hekeus@6: samer@14: if (vg->inTriangle){ samer@14: sendPosition(*vg); samer@15: if (sendStart && vg->isActive){ samer@15: ofxOscMessage m; samer@15: ///track id x y left right top bottom area samer@15: m.setAddress( "/start" ); samer@15: m.addIntArg( vg->id ); samer@15: sender.sendMessage( m ); samer@15: printf("sent /start %i \n",vg->id); hekeus@6: } hekeus@6: } hekeus@6: } hekeus@6: }; samer@10: samer@10: //let's draw our triangle samer@11: ofSetLineWidth(2); samer@12: ofSetColor(96,96,96); samer@10: ofFill(); samer@10: ofTriangle(x1, y1, x2, y2, x3, y3); samer@12: if (constrained) ofSetColor(255,96,96); samer@10: samer@10: // draw smooth edge, brighter if a token is constrained samer@10: ofNoFill(); samer@10: ofTriangle(x1, y1, x2, y2, x3, y3); samer@10: hekeus@6: for (int i=0; iisInVoice(mouseX,mouseY)){ samer@12: Voice *v=voices[i]; samer@12: switch (key) { samer@12: case 'a': { samer@12: ofxOscMessage m; samer@12: const char *addr = v->isActive ? "/stop" : "/start"; samer@12: v->isActive=!v->isActive; samer@12: m.setAddress(addr); samer@12: m.addIntArg(v->id ); samer@12: sender.sendMessage( m ); samer@12: printf("sent %s %i \n",addr,v->id); samer@12: break; samer@12: } samer@12: case OF_KEY_LEFT: sendShift(v->id,-1,2); break; samer@12: case OF_KEY_RIGHT: sendShift(v->id,1,2); break; samer@12: case OF_KEY_UP: sendPeriod(v->id,1,2); break; samer@12: case OF_KEY_DOWN: sendPeriod(v->id,2,1); break; samer@12: case '.': sendPeriod(v->id,1,3); break; samer@12: case ',': sendPeriod(v->id,3,1); break; samer@12: case '+': sendOctave(v->id, ++v->octave); break; samer@12: case '-': sendOctave(v->id, --v->octave); break; samer@13: case '*': sendAmplitude(v->id, v->louder()); break; samer@13: case '/': sendAmplitude(v->id, v->quieter()); break; samer@13: default: printf("unrecognised key: %d.\n",key); samer@12: } hekeus@6: } hekeus@6: } hekeus@6: } hekeus@6: } hekeus@6: } hekeus@6: } hekeus@6: hekeus@6: //-------------------------------------------------------------- hekeus@6: void melodyTriangle::keyReleased (int key){ hekeus@6: hekeus@6: } hekeus@6: hekeus@6: //-------------------------------------------------------------- hekeus@6: void melodyTriangle::mouseMoved(int x, int y ){ hekeus@6: for (int i=0; i