diff options
| author | Tim Redfern <tim@eclectronics.org> | 2011-12-20 13:55:44 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2011-12-20 13:55:44 +0000 |
| commit | 3a0fe9a2700596abe8e29f042ca967f57cc014d7 (patch) | |
| tree | f904f12f433542c09385631479c4c32a8382a3ce /src | |
Diffstat (limited to 'src')
| -rwxr-xr-x | src/globeLayer.cpp | 277 | ||||
| -rwxr-xr-x | src/globeLayer.h | 101 | ||||
| -rwxr-xr-x | src/main.cpp | 17 | ||||
| -rwxr-xr-x | src/testApp.cpp | 199 | ||||
| -rwxr-xr-x | src/testApp.h | 42 |
5 files changed, 636 insertions, 0 deletions
diff --git a/src/globeLayer.cpp b/src/globeLayer.cpp new file mode 100755 index 0000000..17b1fec --- /dev/null +++ b/src/globeLayer.cpp @@ -0,0 +1,277 @@ +#include "globeLayer.h"
+globeLayer::globeLayer()
+{
+ x=y=0.0f;
+ w=ofGetWindowWidth();
+ h=ofGetWindowHeight();
+ mixAmount=1.0f;
+}
+globeLayer::globeLayer(map<string,string> * _settings)
+{
+ settings=map<string,string>(*_settings);
+ x=ofToFloat(settings["x"]);
+ y=ofToFloat(settings["y"]);
+ w=ofToFloat(settings["w"]);
+ h=ofToFloat(settings["h"]);
+ note=ofToInt(settings["note"]);
+ mix=ofToInt(settings["mix"]);
+ if (mix>0) mixAmount=0.0f;
+ else mixAmount=1.0f;
+ active=false;
+
+ printf("layer created, %fx%f\n",w,h);
+}
+void globeLayer::draw() {
+ if (mixAmount<1.0f) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE);
+ glBlendColor(1.0f,1.0f,1.0f, mixAmount);
+ }
+ else glDisable(GL_BLEND);
+}
+void globeLayer::update() {
+}
+void globeLayer::setActive(bool _active){
+ active=_active;
+}
+/*
+void globeLayer::setMixAmt(float _mixAmt){
+ mixAmount=_mixAmt;
+}
+*/
+void globeLayer::CC(int _controller,int _value) {
+ if (_controller==mix) mixAmount=((float)_value)/127.0f;
+ //printf("layer: mix %f\n",mixAmount);
+}
+
+//====================================================
+
+globePlayer::globePlayer(map<string,string> * _settings)
+:globeLayer(_settings)
+{
+ fileName=settings["name"];
+ if(player.loadMovie(fileName)) {
+ printf("globePlayer: loaded %s\n",fileName.c_str());
+ player.setLoopState(OF_LOOP_NORMAL);
+ }
+ else printf("globePlayer: could not load %s\n",fileName.c_str());
+
+ isPlaying=false;
+}
+globePlayer::~globePlayer()
+{
+
+}
+void globePlayer::CC(int _controller,int _value){
+ globeLayer::CC(_controller,_value);
+}
+
+void globePlayer::update()
+{
+ if (!isPlaying&&active) {
+ player.setFrame(0);
+ player.setSpeed(1.0f);
+ player.play();
+ isPlaying=true;
+ }
+ if (isPlaying&&!active) {
+ player.stop();
+ isPlaying=false;
+ }
+ if (active) player.idleMovie();
+
+}
+void globePlayer::draw()
+{
+ if (active) {
+ globeLayer::draw();
+ player.draw(x,y,w,h);
+ }
+}
+
+//====================================================
+
+globeGrabber::globeGrabber(map<string,string> * _settings)
+:globeLayer(_settings)
+{
+ camWidth=ofToInt(settings["grabW"]);
+ camHeight=ofToInt(settings["grabH"]);
+
+ //grabber.setVerbose(true);
+ grabber.listDevices();
+ int device=ofToInt(settings["device"]);
+ if (device>0) {
+ //grabber.setDeviceID(device);
+ printf("using device %i\n",device);
+ }
+ grabber.initGrabber(camWidth,camHeight);
+
+ deInterlace=ofToInt(settings["deInt"])!=0;
+
+ outTexture.allocate(camWidth,camHeight, GL_RGB);
+
+ gammamap=new unsigned char[256];
+ line1=new unsigned char[camWidth];
+ line2=new unsigned char[camWidth];
+ outBuffer=new unsigned char[camWidth*camHeight*3];
+
+ whitePt=ofToFloat(settings["whitePoint"]);
+ blackPt=ofToFloat(settings["blackPoint"]);
+ gamma=ofToFloat(settings["gamma"]);
+
+ whitePCtl=ofToInt(settings["whitePtCtl"]);
+ blackPCtl=ofToInt(settings["blackPtCtl"]);
+ gammaCtl=ofToInt(settings["gammaCtl"]);
+ devCtl=ofToInt(settings["devCtl"]);
+
+ redCtl=ofToInt(settings["redCtl"]);
+ blueCtl=ofToInt(settings["blueCtl"]);
+ greenCtl=ofToInt(settings["greenCtl"]);
+
+ calcGammaMap();
+
+ lineOffset=ofToInt("lineOffset");
+
+ field2=false;
+ use2fields=true;
+
+ red=green=blue=1.0;
+
+
+
+ flip=false;
+ flipCtl=ofToInt(settings["flipCtl"]);
+
+ printf("grabber: RGB %f,%f,%f %f-%f-%f\n",red,green,blue,whitePt,blackPt,gamma);
+}
+globeGrabber::~globeGrabber()
+{
+}
+void globeGrabber::calcGammaMap(){
+ for (int i=0;i<256;i++){
+ //gammamap[i]=(unsigned char)(min(1.0f,pow(max(0.0f,(float(i)/180.0f)-0.4f),0.5f))*255.0);
+
+ float ewp=max(whitePt,blackPt+0.1f); //limit range to 0.1
+ gammamap[i]=(unsigned char)(pow(min(1.0f,max(0.0f,(((float(i)/255.0f)-blackPt)/(ewp-blackPt)))),gamma)*255.0);
+ }
+} +unsigned char globeGrabber::gsGammaMap(unsigned char *pixel) { + return gammamap[(unsigned char)((((int(pixel[0])*76)+(int(pixel[1])*150)+(int(pixel[2]))*28))>>8)]; +}
+void globeGrabber::CC(int _controller,int _value){
+ globeLayer::CC(_controller,_value);
+ //add some colour settings
+ if (_controller==whitePCtl||_controller==blackPCtl||_controller==gammaCtl){
+ if (_controller==whitePCtl) whitePt=((float)_value)/127.0;
+ if (_controller==blackPCtl) blackPt=((float)_value)/127.0;
+ if (_controller==gammaCtl) gamma=(((float)_value)/63.0)+0.1f; //0.1-2.1
+ calcGammaMap();
+ }
+ if (_controller==redCtl) red=((float)_value)/127.0;
+ if (_controller==blueCtl) blue=((float)_value)/127.0;
+ if (_controller==greenCtl) green=((float)_value)/127.0;
+ if (_controller==flipCtl) flip=_value>63;
+ if (_controller==devCtl) {
+ grabber.close();
+ grabber.setDeviceID(_value);
+ grabber.initGrabber(camWidth,camHeight);
+ printf("Grabber changed to device %i\n",_value);
+
+ }
+
+ //printf("grabber: RGB %f,%f,%f %f-%f-%f\n",red,green,blue,blackPt,gamma,whitePt);
+}
+void globeGrabber::update() +{ + if (active) grabber.grabFrame(); + if (grabber.isFrameNew()){ + int time=ofGetElapsedTimeMillis(); + frameTime=time-grabTime; + grabTime=time; + unsigned char * pixels = grabber.getPixels(); + if(!deInterlace) { + int totalPixels = camWidth*camHeight; + for (int i = 0; i < totalPixels; i++){ + unsigned char gs=(unsigned char)((int(pixels[i*3])+int(pixels[i*3+1])+int(pixels[i*3+2]))/3); + outBuffer[i*3] = gammamap[gs]; + outBuffer[i*3+1] = gammamap[gs]; + outBuffer[i*3+2] = gammamap[gs]; + } + } + else { + field2=true; + unsigned char* lp1=line1; + unsigned char* lp2=line2; + unsigned char* tp; + int j = 0; + for (int i=0;i<camWidth;i++) lp1[i]=gsGammaMap(&pixels[(((j*camWidth)+i)*3)]); + //lp1[i]=gammamap[(unsigned char)((int(pixels[(((j*camWidth)+i)*3)])+int(pixels[(((j*camWidth)+i)*3)+1])+int(pixels[(((j*camWidth)+i)*3)+2]))/3)];// + //lp1[i]=gsGammaMap(&pixels[(((j*camWidth)+i)*3)]); + // + for (j = 2; j < camHeight; j+=2){ + for (int i=0;i<camWidth;i++) { + //lp2[i]=gsGammaMap(&pixels[(((j*camWidth)+i)*3)]); + lp2[i]=gammamap[(unsigned char)((int(pixels[(((j*camWidth)+i)*3)])+int(pixels[(((j*camWidth)+i)*3)+1])+int(pixels[(((j*camWidth)+i)*3)+2]))/3)]; + unsigned char mp=(unsigned char)((int(lp1[i])+int(lp2[i]))/2); + outBuffer[(j*camWidth+i)*3] = mp; + outBuffer[(j*camWidth+i)*3+1] = mp; + outBuffer[(j*camWidth+i)*3+2] = mp; + outBuffer[((j+1)*camWidth+i)*3] = lp2[i]; + outBuffer[((j+1)*camWidth+i)*3+1] = lp2[i]; + outBuffer[((j+1)*camWidth+i)*3+2] = lp2[i]; + } + tp=lp1; + lp1=lp2; + lp2=tp; + } + } + outTexture.loadData(outBuffer, camWidth,camHeight, GL_RGB); + } + if (deInterlace&&use2fields&&field2&&((ofGetElapsedTimeMillis()-grabTime)>=(frameTime/2))){ + field2=false; + unsigned char * pixels = grabber.getPixels(); + unsigned char* lp1=line1; + unsigned char* lp2=line2; + unsigned char* tp; + int j = 1; + for (int i=0;i<camWidth;i++) lp1[i]=gammamap[(unsigned char)((int(pixels[(((j*camWidth)+i)*3)])+int(pixels[(((j*camWidth)+i)*3)+1])+int(pixels[(((j*camWidth)+i)*3)+2]))/3)]; + for (j = 3; j < camHeight-1; j+=2){ + for (int i=0;i<camWidth;i++) { + lp2[i]=gammamap[(unsigned char)((int(pixels[(((j*camWidth)+i)*3)])+int(pixels[(((j*camWidth)+i)*3)+1])+int(pixels[(((j*camWidth)+i)*3)+2]))/3)]; + char mp=(unsigned char)((int(lp1[i])+int(lp2[i]))/2); + outBuffer[(j*camWidth+i)*3] = mp; + outBuffer[(j*camWidth+i)*3+1] = mp; + outBuffer[(j*camWidth+i)*3+2] = mp; + outBuffer[((j+1)*camWidth+i)*3] = lp2[i]; + outBuffer[((j+1)*camWidth+i)*3+1] = lp2[i]; + outBuffer[((j+1)*camWidth+i)*3+2] = lp2[i]; + } + tp=lp1; + lp1=lp2; + lp2=tp; + } + outTexture.loadData(outBuffer, camWidth,camHeight, GL_RGB); + } + +}
+void globeGrabber::draw()
+{
+
+ if (active) {
+ //globeLayer::draw();
+ /*
+ if (mixAmount<1.0f) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE);
+ glBlendColor(red,green,blue, mixAmount);
+ }
+ else glDisable(GL_BLEND);
+ */
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_CONSTANT_COLOR,GL_ONE);
+ glBlendColor(red*mixAmount,green*mixAmount,blue*mixAmount, 1.0f);
+ if (flip) outTexture.draw(x+w,y,-w,h);
+ else outTexture.draw(x,y,w,h);
+ }
+
+}
diff --git a/src/globeLayer.h b/src/globeLayer.h new file mode 100755 index 0000000..781750a --- /dev/null +++ b/src/globeLayer.h @@ -0,0 +1,101 @@ +#ifndef GLOBELAYER_H
+#define GLOBELAYER_H
+
+#include "ofMain.h"
+
+class globeLayer
+{
+ public:
+ globeLayer();
+ globeLayer(map<string,string> * _settings);
+
+ virtual void update();
+ virtual void draw();
+ void setActive(bool _active);
+ //void setMixAmt(float _mixAmt);
+
+ int note,mix; //midi note to play and controller to mix
+
+ virtual void CC(int _controller,int _value); //control change is sent to all channels
+
+ //colour changing and setting functions
+ protected:
+ float x,y; //pos on screen
+ float w,h; //size on screen
+ bool active;
+ float mixAmount;
+
+ map<string,string>settings; //copy of settings key (is neecesary?)
+ //char* CCs; //registers interest for midi CC messages
+
+ private:
+
+};
+
+
+class globePlayer: public globeLayer
+{
+ public:
+ globePlayer();
+ globePlayer(map<string,string> * _settings);
+ ~globePlayer();
+
+ void update();
+ void draw();
+
+ void CC(int _controller,int _value); //have to override virtual function
+
+ private:
+ bool isPlaying;
+ string fileName;
+ ofVideoPlayer player;
+};
+
+class globeGrabber: public globeLayer
+{
+ public:
+ globeGrabber();
+ globeGrabber(map<string,string> * _settings);
+ ~globeGrabber();
+
+ void update();
+ void draw();
+
+ void CC(int _controller,int _value); //add some colour settings
+
+ protected:
+ void calcGammaMap();
+
+ private:
+ bool isPlaying;
+
+ ofVideoGrabber grabber;
+
+ int camWidth,camHeight;
+
+ unsigned char* gammamap; + unsigned char gsGammaMap(unsigned char *pixel);
+
+ unsigned char* line1;
+ unsigned char* line2;
+ bool deInterlace;
+ ofTexture outTexture;
+
+ unsigned char* outBuffer;
+
+ bool field2; //flag that there is a 2nd field waiting to be processed
+ bool use2fields;
+ int frameTime,grabTime; //keep track of field timing
+
+ int whitePCtl,blackPCtl,gammaCtl,redCtl,blueCtl,greenCtl,devCtl;
+ float whitePt,blackPt,gamma;
+
+ float red,green,blue;
+
+ int lineOffset;
+ bool flip;
+ int flipCtl;
+
+};
+
+#endif // GLOBELAYER_H
diff --git a/src/main.cpp b/src/main.cpp new file mode 100755 index 0000000..6809b1c --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,17 @@ +#include "ofMain.h" +#include "testApp.h" +#include "ofAppGlutWindow.h" + +//======================================================================== +int main( ){ + + ofAppGlutWindow window; + //ofSetupOpenGL(&window, 1440,900, OF_FULLSCREEN); // <-------- setup the GL context + ofSetupOpenGL(&window, 1024,768, OF_FULLSCREEN); + + // this kicks off the running of my app + // can be OF_WINDOW or OF_FULLSCREEN + // pass in width and height too: + ofRunApp( new testApp()); + +} diff --git a/src/testApp.cpp b/src/testApp.cpp new file mode 100755 index 0000000..ab5fcbb --- /dev/null +++ b/src/testApp.cpp @@ -0,0 +1,199 @@ +#include "testApp.h" + + +//-------------------------------------------------------------- +void testApp::setup(){ + int midiPort=0; + midiChannel=0; + numLayers=0; + if( !XML.loadFile("settings.xml") ){ + printf("unable to load settings.xml check data/ folder\n"); + }else{ + printf("settings loaded!\n"); + midiPort=ofToInt(XML.getAttribute("globePlayer", "port", "0")); //default to 0/all + midiChannel=ofToInt(XML.getAttribute("globePlayer", "channel", "0")); + if (midiChannel) printf("listening on midi channel %d\n",midiChannel); + else printf("listening on all midi channels\n"); + if(XML.pushTag("globePlayer")) { + numLayers=XML.getNumTags("layer"); + if(numLayers) { + layers=new globeLayer*[numLayers]; + for (int i=0;i<numLayers;i++){ + XML.pushTag("layer",i); + string layerType=XML.getAttribute("content", "type", ""); + XML.pushTag("content"); + vector<string>keys; + XML.getAttributeNames("settings", keys, 0); + map<string,string> settings; + for (int k=0;k<keys.size();k++) { + settings[keys[k]]=XML.getAttribute("settings",keys[k],"none",0); + } + if (layerType=="player") layers[i]=new globePlayer(&settings); + if (layerType=="grabber") layers[i]=new globeGrabber(&settings); + XML.popTag(); + XML.popTag(); + } + } + } + if (numLayers==0) printf("no layers loaded!\n"); + } + + midiIn.listPorts(); + midiIn.openPort(midiPort); + midiIn.addListener(this); + + // to register only to one controller pass the id as first argument + // midiIn.addListener(84,this); + + // to debug + // midiIn.setVerbose(true); + showFPS=false; +} + +//-------------------------------------------------------------- +void testApp::update(){ + for (int i=0;i<numLayers;i++) layers[i]->update(); +} + +//-------------------------------------------------------------- +void testApp::draw(){ + ofBackground(0,0,0); + + for (int i=0;i<numLayers;i++) layers[i]->draw(); + + if (showFPS) ofDrawBitmapString(ofToString(ofGetFrameRate(), 2),20,20); + +} + +//-------------------------------------------------------------- +void testApp::keyPressed (int key){ + if(key == 's'){ + XML.saveFile("settings.xml"); + printf("settings saved!\n"); + } + if(key == 'f'){ + toggleFPS(); + } + if(key=='1'){ + layers[0]->setActive(100); + layers[0]->CC(8,127); + } + if(key=='q'){ + layers[0]->setActive(0); + layers[0]->CC(8,0); + } + if(key=='2'){ + layers[1]->setActive(100); + layers[1]->CC(9,127); + } + if(key=='w'){ + layers[1]->setActive(0); + layers[1]->CC(9,0); + } + if(key=='3'){ + layers[2]->setActive(100); + layers[2]->CC(10,127); + } + if(key=='e'){ + layers[2]->setActive(0); + layers[2]->CC(10,0); + } + if(key=='7'){ + layers[2]->CC(20,3); + printf("changing to device 3\n"); + + } + if(key=='8'){ + layers[2]->CC(20,4); + printf("changing to device 4\n"); + } + //this doesn't seem to arrive + if(key=='4'){ + layers[3]->setActive(100); + layers[3]->CC(16,127); + } + if(key=='r'){ + layers[3]->setActive(0); + layers[3]->CC(16,0); + } + +} + +//-------------------------------------------------------------- +void testApp::keyReleased(int key){ + +} + +//-------------------------------------------------------------- +void testApp::mouseMoved(int x, int y ){ + +} + +//-------------------------------------------------------------- +void testApp::mouseDragged(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::mouseReleased(int x, int y, int button){ + + +} +void testApp::mousePressed(int x, int y, int button) { +} + +//-------------------------------------------------------------- +void testApp::windowResized(int w, int h){ + +} + +//-------------------------------------------------------------- +void testApp::gotMessage(ofMessage msg){ + +} + +//-------------------------------------------------------------- +void testApp::dragEvent(ofDragInfo dragInfo){ + +} + +void testApp::toggleFPS(){ + showFPS=!showFPS; +} + +void testApp::newMidiMessage(ofxMidiEventArgs& eventArgs){ + + //newMessage(eventArgs.port, eventArgs.channel, eventArgs.byteTwo, eventArgs.timestamp); + +//byteOne : message type + + /* + int port; + int channel; + int status; + int byteOne; + int byteTwo; + double timestamp; + */ + + //printf("%d %d %d %d %d\n",eventArgs.port,eventArgs.channel,eventArgs.status,eventArgs.byteOne,eventArgs.byteTwo); + + bool noteOn; //this old thing! + + if ((midiChannel==0)||(eventArgs.channel==midiChannel)) { + switch(eventArgs.status) { + case 144: //noteon-off + noteOn=(eventArgs.byteTwo==0?false:true); + for (int i=0;i<numLayers;i++){ + if (layers[i]->note==eventArgs.byteOne) layers[i]->setActive(noteOn); + } + break; + case 176: //control change + for (int i=0;i<numLayers;i++){ + //if (layers[i]->mix==eventArgs.byteOne) layers[i]->setMixAmt(((float)eventArgs.byteTwo)/127.0f); + layers[i]->CC(eventArgs.byteOne,eventArgs.byteTwo); + } + } + } +} + diff --git a/src/testApp.h b/src/testApp.h new file mode 100755 index 0000000..df989df --- /dev/null +++ b/src/testApp.h @@ -0,0 +1,42 @@ +#pragma once + +#include "ofMain.h" +#include "ofxXmlSettings.h" + +#include "globeLayer.h" + +#define OF_ADDON_USING_OFXMIDIIN + +#include "ofxMidi.h" + +class testApp : public ofBaseApp, public ofxMidiListener{ + + public: + + void setup(); + void update(); + void draw(); + + void keyPressed(int key); + void keyReleased(int key); + void mouseMoved(int x, int y ); + void mouseDragged(int x, int y, int button); + void mousePressed(int x, int y, int button); + void mouseReleased(int x, int y, int button); + void windowResized(int w, int h); + void dragEvent(ofDragInfo dragInfo); + void gotMessage(ofMessage msg); + + void toggleFPS(); + bool showFPS; + + ofxXmlSettings XML; + + globeLayer** layers; + int numLayers; + + int midiChannel; + ofxMidiIn midiIn; + void newMidiMessage(ofxMidiEventArgs& eventArgs); +}; + |
