summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--03_play/src/testApp.cpp27
-rw-r--r--04_playobjects/src/testApp.cpp17
-rw-r--r--04_playobjects/src/testApp.h95
-rw-r--r--06_performance/Makefile2
-rw-r--r--06_performance/Makfile244
-rwxr-xr-x06_performance/addons.make3
-rwxr-xr-x06_performance/config.mak56
-rw-r--r--06_performance/config.make56
-rw-r--r--06_performance/src/FFTOctaveAnalyzer.cpp98
-rw-r--r--06_performance/src/FFTOctaveAnalyzer.h45
-rw-r--r--06_performance/src/fft.cpp489
-rw-r--r--06_performance/src/fft.h33
-rw-r--r--06_performance/src/main.cpp17
-rw-r--r--06_performance/src/oni.cpp1
-rw-r--r--06_performance/src/oni.h1
-rw-r--r--06_performance/src/testApp.cpp776
-rw-r--r--06_performance/src/testApp.h163
17 files changed, 2044 insertions, 79 deletions
diff --git a/03_play/src/testApp.cpp b/03_play/src/testApp.cpp
index 3095a18..02b7901 100644
--- a/03_play/src/testApp.cpp
+++ b/03_play/src/testApp.cpp
@@ -1,5 +1,8 @@
#include "testApp.h"
+//next.
+//the real project
+
//texture binding with normalised coords
void bindTexture(ofBaseHasTexture &t) {
ofTexture &tex = t.getTextureReference();
@@ -73,7 +76,7 @@ void testApp::setup() {
camera.setPosition(0,0,-500);
camera.lookAt(target,ofVec3f(0,1,0));
- point_texture.loadImage("spriteA.png");
+ //point_texture.loadImage("spriteA.png");
}
@@ -89,13 +92,13 @@ void testApp::startPlayers(){
//openNIPlayers[deviceID].setPaused(true);
- //soundplayer.stop();
+ soundplayer.stop();
- //if (recs[playing].audio!=""){
- // soundplayer.loadSound(recs[playing].audio);
- // soundplayer.play();
- // soundplayer.setPosition(offset);
- //}
+ if (recs[playing].audio!=""){
+ soundplayer.loadSound(recs[playing].audio);
+ soundplayer.play();
+ soundplayer.setPosition(offset);
+ }
}
}
@@ -131,12 +134,12 @@ void testApp::draw(){
- glActiveTexture(GL_TEXTURE0);
- glEnable( GL_TEXTURE_2D );
+ //glActiveTexture(GL_TEXTURE0);
+ //glEnable( GL_TEXTURE_2D );
//glTexEnv(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
//glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//glBindTexture(GL_TEXTURE_2D, texture_name);
- bindTexture(point_texture);
+ //bindTexture(point_texture);
//ofEnablePointSprites();
for (int deviceID = 0; deviceID < numDevices; deviceID++){
@@ -187,7 +190,7 @@ void testApp::draw(){
//for (int j=0;j<openNIPlayers[deviceID].getHeight();j+=20) {
- for (int o=0;o<2000;o++) { //100 new points per frame
+ for (int o=0;o<100;o++) { //100 new points per frame
int i=ofRandom(openNIPlayers[deviceID].getWidth());
int j=ofRandom(openNIPlayers[deviceID].getHeight());
@@ -248,7 +251,7 @@ void testApp::draw(){
}
//ofDisablePointSprites();
- unbindTexture(point_texture);
+ //unbindTexture(point_texture);
ofSetColor(255, 255, 255);
string msg = "MILLIS: " + ofToString(ofGetElapsedTimeMillis());
diff --git a/04_playobjects/src/testApp.cpp b/04_playobjects/src/testApp.cpp
index fe26030..cfe6119 100644
--- a/04_playobjects/src/testApp.cpp
+++ b/04_playobjects/src/testApp.cpp
@@ -37,6 +37,10 @@ void testApp::setup() {
receiver.setup(OSCPORT);
drawmovies=false;drawcloud=false;
+
+ target.setPosition(0,0,0);
+ camera.setPosition(0,0,-500);
+ camera.lookAt(target,ofVec3f(0,1,0));
}
void testApp::startPlayers(int newplayer){
@@ -84,11 +88,14 @@ void testApp::draw(){
}
if (drawcloud) {
- //cam.begin();
- ofTranslate(ofGetWidth(), ofGetHeight()/2,0);
+ camera.begin();
+
+ ofPushMatrix();
+ ofRotateY(ofGetElapsedTimef()*2.0f);
+ ofTranslate(0,0,-1100);
players[playing].drawCloud();
- ofDrawAxis(100);
- //cam.end();
+ ofPopMatrix();
+ camera.end();
}
}
@@ -100,7 +107,7 @@ void testApp::draw(){
msg += "\nclip: "+ofToString(playing);
if (playing>-1) msg += "\n"+players[playing].audio;
msg += "\noffset: "+ofToString(offset);
- if (drawcloud>-1) msg += "\nwith cloud";
+ if (drawcloud) msg += "\nwith cloud";
verdana.drawString(msg, 10, 10);
}
diff --git a/04_playobjects/src/testApp.h b/04_playobjects/src/testApp.h
index e1f1e5c..873db31 100644
--- a/04_playobjects/src/testApp.h
+++ b/04_playobjects/src/testApp.h
@@ -20,7 +20,13 @@ struct record{
//in order to play different clips it seems necessary to have a player per clip
class syncOniPlayer{
public:
- syncOniPlayer() {drawable=false;}
+ int depthW;
+ int depthH;
+ syncOniPlayer() {
+ drawable=false;
+ depthW=320;
+ depthH=240;
+ }
~syncOniPlayer(){
stop();
}
@@ -80,100 +86,64 @@ class syncOniPlayer{
players[i]->drawDepth(50, 0,520,390);
players[i]->drawImage(600, 0,520,390);
- const XnDepthPixel* depthmap=players[i]->getDepthGenerator().GetDepthMap();
-
+ int count;
+ for (int i=0;i<players.size();i++) {
- int range=2500;
+ const XnDepthPixel* depthmap=players[i]->getDepthGenerator().GetDepthMap();
+ //uint16_t* depthpixels=depthmap.getPixels();
+ int range=2500;
-
- int dmw=players[i]->getWidth();
-
- //for (int i=0;i<players[i]->getWidth();i+=2) {
+ for (int i=0;i<depthW;i+=2) {
glBegin(GL_LINES);
- //for (int j=0;j<players[i]->getHeight();j+=2) {
+ for (int j=0;j<depthH;j+=2) {
- ofPoint p= players[i]->projectiveToWorld(ofPoint(300,150,(float)(depthmap[1200])));
-/*
- ofPoint p= players[i]->projectiveToWorld(ofPoint(i,j,(float)(depthmap[j*dmw+i])));
+
+ ofPoint p= players[i]->projectiveToWorld(ofPoint(i,j,(float)(depthmap[j*depthW+i])));
//ofPoint p= projectiveToWorld(ofPoint(i,j,(float)depthmap[j*dmw+i]));
- if (p.z == 0 || p.z>range) continue; // gets rid of background -> still a bit weird if userID > 0... //&& isCPBkgnd
- //ofColor color = kinect->getColorAt(x,y); //userID);
- //if (col) glColor4ub((unsigned char)color.r, (unsigned char)color.g, (unsigned char)color.b, (unsigned char)color.a);
- // else
+ //if (p.z == 0 || p.z>range) continue; // gets rid of background
- glColor4ub((unsigned char)255, (unsigned char)255, (unsigned char)255, (unsigned char)255);
- glVertex3f(p.x, p.y, p.z);
+ //glColor4ub((unsigned char)255, (unsigned char)255, (unsigned char)255, (unsigned char)255);
+ //glVertex3f(p.x, p.y, p.z);
//if (i==320&&j==160) cerr<<"world point: "<<p.x<<","<<p.y<<","<<p.z<<endl;
- */
- //}
+ }
glEnd();
- //}
+ }
+
+ }
+
}
}
void drawCloud(){
- /*
- int num=0;
- for (int i=0;i<players.size();i++) {
- ofPushMatrix();
- ofEnableBlendMode(OF_BLENDMODE_ALPHA);
- int numUsers = players[i]->getNumTrackedUsers();
- for (int nID = 0; nID < numUsers; nID++){
- ofxOpenNIUser & user = players[i]->getTrackedUser(nID);
- //user.drawMask();
- ofPushMatrix();
- ofTranslate(0,0,-1000);
- user.drawPointCloud();
- ofPopMatrix();
- }
- num+=numUsers;
- ofDisableBlendMode();
- ofPopMatrix();
- }
- return num;
- */
- //cerr<<"drawing "<<players.size()<<" clouds"<<endl; we are getting to here when unititialised
-
+
int count;
for (int i=0;i<players.size();i++) {
- if (players[i]==0x00) {
- cerr<<"more spooky shit....!";
- return;
- }
const XnDepthPixel* depthmap=players[i]->getDepthGenerator().GetDepthMap();
//uint16_t* depthpixels=depthmap.getPixels();
int range=2500;
-
-
- int dmw=players[i]->getWidth();
-
- for (int i=0;i<players[i]->getWidth();i+=2) {
+ for (int i=0;i<depthW;i+=2) {
glBegin(GL_LINES);
- for (int j=0;j<players[i]->getHeight();j+=2) {
-
+ for (int j=0;j<depthH;j+=2) {
- ofPoint p= players[i]->projectiveToWorld(ofPoint(i,j,(float)(depthmap[j*dmw+i])));
+ ofPoint p= players[i]->projectiveToWorld(ofPoint(i,j,(float)(depthmap[j*depthW+i])));
//ofPoint p= projectiveToWorld(ofPoint(i,j,(float)depthmap[j*dmw+i]));
- if (p.z == 0 || p.z>range) continue; // gets rid of background -> still a bit weird if userID > 0... //&& isCPBkgnd
- //ofColor color = kinect->getColorAt(x,y); //userID);
- //if (col) glColor4ub((unsigned char)color.r, (unsigned char)color.g, (unsigned char)color.b, (unsigned char)color.a);
- // else
+ //if (p.z == 0 || p.z>range) continue; // gets rid of background
- glColor4ub((unsigned char)255, (unsigned char)255, (unsigned char)255, (unsigned char)255);
- glVertex3f(p.x, p.y, p.z);
+ //glColor4ub((unsigned char)255, (unsigned char)255, (unsigned char)255, (unsigned char)255);
+ //glVertex3f(p.x, p.y, p.z);
//if (i==320&&j==160) cerr<<"world point: "<<p.x<<","<<p.y<<","<<p.z<<endl;
}
@@ -243,7 +213,8 @@ public:
bool drawmovies,drawcloud;
int offset;
- ofxMayaCam cam;
+ ofCamera camera;
+ ofNode target;
};
diff --git a/06_performance/Makefile b/06_performance/Makefile
new file mode 100644
index 0000000..2d83a77
--- /dev/null
+++ b/06_performance/Makefile
@@ -0,0 +1,2 @@
+include config.make
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/Makefile.examples
diff --git a/06_performance/Makfile b/06_performance/Makfile
new file mode 100644
index 0000000..0ae1f0e
--- /dev/null
+++ b/06_performance/Makfile
@@ -0,0 +1,244 @@
+# openFrameworks OS X makefile
+#
+# make help : shows this message
+# make Debug: makes the application with debug symbols
+# make Release: makes the app with optimizations
+# make: the same as make Release
+# make CleanDebug: cleans the Debug target
+# make CleanRelease: cleans the Release target
+# make clean: cleans everything
+#
+#
+# this should work with any OF app, just copy any example
+# change the name of the folder and it should compile
+# only .cpp support, don't use .c files
+# it will look for files in any folder inside the application
+# folder except that in the EXCLUDE_FROM_SOURCE variable
+# it doesn't autodetect include paths yet
+# add the include paths in the USER_CFLAGS variable
+# using the gcc syntax: -Ipath
+#
+# to add addons to your application, edit the addons.make file
+# in this directory and add the names of the addons you want to
+# include
+#
+# edit the following vars to customize the makefile
+
+include config.mak
+ARCH = i386
+
+COMPILER_OPTIMIZATION = $(USER_COMPILER_OPTIMIZATION)
+
+EXCLUDE_FROM_SOURCE="bin,.xcodeproj,obj"
+
+# you shouldn't modify anything below this line
+SHELL = /bin/sh
+CXX = g++
+LIBSPATH=osx
+
+NODEPS = clean
+SED_EXCLUDE_FROM_SRC = $(shell echo $(EXCLUDE_FROM_SOURCE) | sed s/\,/\\\\\|/g)
+SOURCE_DIRS = src
+#$(shell find . -maxdepth 1 -mindepth 1 -type d | grep -v $(SED_EXCLUDE_FROM_SRC) | sed s/.\\///)
+SOURCES = $(shell find $(SOURCE_DIRS) -name "*.cpp" -or -name "*.c")
+OBJFILES = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))
+APPNAME = $(shell basename `pwd`)
+CORE_INCLUDES = $(shell find $(OF_ROOT)/libs/openFrameworks/ -type d)
+CORE_INCLUDE_FLAGS = $(addprefix -I,$(CORE_INCLUDES))
+INCLUDES = $(shell find $(OF_ROOT)/libs/*/include -type d | grep -v glu | grep -v quicktime | grep -v poco)
+INCLUDES_FLAGS = $(addprefix -I,$(INCLUDES))
+INCLUDES_FLAGS += -I$(OF_ROOT)/libs/poco/include
+INCLUDES_FLAGS += -I$(OF_ROOT)/libs/glu/include
+#INCLUDES_FLAGS += -I$(OF_ROOT)/libs/quicktime/include
+
+LIB_STATIC = $(shell ls $(OF_ROOT)/libs/*/lib/$(LIBSPATH)/*.a | grep -v openFrameworksCompiled | grep -v poco)
+LIB_STATIC += $(OF_ROOT)/libs/fmodex/lib/osx/libfmodex.dylib
+LIB_SHARED = $(shell ls $(OF_ROOT)/libs/*/lib/$(LIBSPATH)/*.so | grep -v openFrameworksCompiled | grep -v poco)
+LIB_STATIC += $(OF_ROOT)/libs/poco/lib/$(LIBSPATH)/PocoNet.a $(OF_ROOT)/libs/poco/lib/$(LIBSPATH)/PocoXML.a $(OF_ROOT)/libs/poco/lib/$(LIBSPATH)/PocoUtil.a $(OF_ROOT)/libs/poco/lib/$(LIBSPATH)/PocoFoundation.a
+LIB_PATHS_FLAGS = $(shell ls -d $(OF_ROOT)/libs/*/lib/$(LIBSPATH) | sed "s/\(\.*\)/-L\1/")
+
+CFLAGS += -Wall -fexceptions
+CFLAGS += -I.
+CFLAGS += $(INCLUDES_FLAGS)
+CFLAGS += $(CORE_INCLUDE_FLAGS)
+CFLAGS += -x c++ -arch $(ARCH) -fmessage-length=0 -pipe -Wno-trigraphs -fpascal-strings -Os -fasm-blocks -Wno-deprecated-declarations -Wno-invalid-offsetof -gdwarf-2 -msse3 -mssse3
+
+LIBS += $(LIB_SHARED)
+LIBS += $(LIB_STATIC)
+
+LDFLAGS = $(LIB_PATHS_FLAGS) -Wl
+LIBS += -F$(OF_ROOT)/libs/glut/lib/osx -framework AppKit -framework Cocoa -framework IOKit -framework AGL -framework AudioToolbox -framework Carbon -framework CoreAudio -CoreFoundation -framework CoreServices -framework GLUT -framework OpenGL -framework Quicktime -framework CoreMidi -framework QTKit -framework QuartzCore -framework CoreVideo -framework Accelerate
+
+#Targets
+ifeq ($(findstring Debug,$(MAKECMDGOALS)),Debug)
+ TARGET_CFLAGS = -g
+ TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/osx/openFrameworksDebug.a
+ TARGET_NAME = Debug
+endif
+
+ifeq ($(findstring Release,$(MAKECMDGOALS)),Release)
+ TARGET_CFLAGS = $(COMPILER_OPTIMIZATION)
+ TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/osx/openFrameworks.a
+ TARGET_NAME = Release
+endif
+
+ifeq ($(findstring Debug,$(MAKECMDGOALS)),Debug)
+ BIN_NAME = $(APPNAME)_debug
+ TARGET = bin/$(BIN_NAME)
+endif
+
+ifeq ($(findstring Release,$(MAKECMDGOALS)),Release)
+ BIN_NAME = $(APPNAME)
+ TARGET = bin/$(BIN_NAME)
+endif
+
+ifeq ($(findstring Release,$(MAKECMDGOALS)),clang)
+ CXX = clang
+endif
+
+ifeq ($(MAKECMDGOALS),)
+ TARGET_NAME = Release
+ BIN_NAME = $(APPNAME)
+ TARGET = bin/$(BIN_NAME)
+ TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/osx/openFrameworks.a
+endif
+
+ifeq ($(MAKECMDGOALS),clean)
+ TARGET = bin/$(APPNAME)_debug bin/$(APPNAME)
+endif
+
+
+#Output
+OBJ_OUTPUT = obj/$(TARGET_NAME)/
+CLEANTARGET = clean$(TARGET_NAME)
+OBJS = $(addprefix $(OBJ_OUTPUT), $(OBJFILES))
+DEPFILES = $(patsubst %.o,%.d,$(OBJS))
+ifeq ($(findstring addons.make,$(wildcard *.make)),addons.make)
+ ADDONS = $(shell cat addons.make)
+ ADDONS_REL_DIRS = $(addsuffix /src, $(ADDONS))
+ ADDONS_LIBS_REL_DIRS = $(addsuffix /libs, $(ADDONS))
+ ADDONS_DIRS = $(addprefix $(OF_ROOT)/addons/, $(ADDONS_REL_DIRS) )
+ ADDONS_LIBS_DIRS = $(addprefix $(OF_ROOT)/addons/, $(ADDONS_LIBS_REL_DIRS) )
+ ADDONS_BIN_LIBS_DIRS = $(addsuffix /*/lib/$(LIBSPATH), $(ADDONS_LIBS_DIRS) )
+ ADDONS_INCLUDES = $(ADDONS_DIRS)
+ ADDONS_INCLUDES = $(ADDONS_LIBS_DIRS)
+ ADDONS_INCLUDES += $(shell find $(ADDONS_DIRS) -type d 2> /dev/null)
+ ADDONS_INCLUDES += $(shell find $(ADDONS_LIBS_DIRS) -type d 2> /dev/null)
+ ADDONSCFLAGS = $(addprefix -I,$(ADDONS_INCLUDES))
+ifeq ($(findstring libsorder.make,$(shell find $(ADDONS_BIN_LIBS_DIRS) -name libsorder.make 2> /dev/null)),libsorder.make)
+ ADDONS_LIBS_W_ORDER = $(shell cat $(shell find $(ADDONS_BIN_LIBS_DIRS) -name libsorder.make 2> /dev/null))
+ SED_EXCLUDE_LIBS = $(addsuffix \|,$(ADDONS_LIBS_W_ORDER))
+ ADDONS_LIBS_STATICS = $(shell find $(ADDONS_BIN_LIBS_DIRS) -name *.a 2> /dev/null | grep -v '$(SED_EXCLUDE_LIBS)')
+ else
+ ADDONS_LIBS_STATICS = $(shell find $(ADDONS_BIN_LIBS_DIRS) -name *.a 2> /dev/null)
+ endif
+
+ ADDONS_LIBS_STATICS += $(addprefix -l, $(ADDONS_LIBS_W_ORDER))
+ ADDONS_LIBS_STATICS += $(addprefix -L, $(shell find $(ADDONS_BIN_LIBS_DIRS) -name libsorder.make 2> /dev/null | sed s/libsorder.make//g))
+ ADDONS_LIBS_SHARED = $(shell find $(ADDONS_BIN_LIBS_DIRS) -name *.so 2> /dev/null)
+ ADDONSLIBS = $(ADDONS_LIBS_STATICS)
+ ADDONSLIBS += $(ADDONS_LIBS_SHARED)
+
+
+ ADDONS_SOURCES = $(shell find $(ADDONS_DIRS) -name "*.cpp" -or -name "*.c" 2> /dev/null)
+ ADDONS_SOURCES += $(shell find $(ADDONS_LIBS_DIRS) -name "*.cpp" -or -name "*.c" -or -name "*.cc" 2>/dev/null)
+ ADDONS_OBJFILES = $(subst $(OF_ROOT)/, ,$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(ADDONS_SOURCES)))))
+ ADDONS_OBJS = $(addprefix $(OBJ_OUTPUT), $(ADDONS_OBJFILES))
+ DEPFILES += $(patsubst %.o,%.d,$(ADDONS_OBJS))
+endif
+
+.PHONY: Debug Release all after
+
+Release: $(TARGET) after
+
+Debug: $(TARGET) after
+
+all:
+ $(MAKE) Release
+
+
+
+#This rule does the compilation
+#$(OBJS): $(SOURCES)
+$(OBJ_OUTPUT)%.o: %.cpp
+ @echo "compiling object for: " $<
+ mkdir -p $(@D)
+ $(CXX) -c $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o$@ -c $<
+
+$(OBJ_OUTPUT)%.o: %.c
+ @echo "compiling object for: " $<
+ mkdir -p $(@D)
+ $(CXX) -c $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o$@ -c $<
+
+
+$(OBJ_OUTPUT)%.o: $(OF_ROOT)/%.cpp
+ @echo "compiling addon object for" $<
+ mkdir -p $(@D)
+ $(CXX) $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o $@ -c $<
+
+$(OBJ_OUTPUT)%.o: $(OF_ROOT)/%.c
+ @echo "compiling addon object for" $<
+ mkdir -p $(@D)
+ $(CXX) $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o $@ -c $<
+
+$(TARGET): $(OBJS) $(ADDONS_OBJS)
+ @echo "linking" $(TARGET) $(GTK)
+ $(CXX) -arch $(ARCH) -v -o $@ $(OBJS) $(ADDONS_OBJS) $(USER_CFLAGS) $(LDFLAGS) $(USER_LDFLAGS) $(TARGET_LIBS) $(ADDONSLIBS) $(USER_LIBS) $(LIBS)
+
+-include $(DEPFILES)
+
+.PHONY: clean cleanDebug cleanRelease
+clean:
+ rm -Rf obj
+ rm -f -v $(TARGET)
+ rm -Rf -v bin/libs
+
+$(CLEANTARGET):
+ rm -Rf -v $(OBJ_OUTPUT)
+ rm -f -v $(TARGET)
+
+after:$(TARGET)
+ @echo Preparing MacOS .app
+ #-rm -rf -v $(TARGET).app
+ mkdir -p $(TARGET).app/Contents/Frameworks
+ mkdir -p $(TARGET).app/Contents/MacOS
+ cp -r $(OF_ROOT)/libs/glut/lib/osx/* $(TARGET).app/Contents/Frameworks/
+ cp -r $(OF_ROOT)/libs/fmodex/lib/osx/* $(TARGET).app/Contents/MacOS/
+ cp $(TARGET) $(TARGET).app/Contents/MacOS/
+ install_name_tool -change ./libfmodex.dylib @executable_path/libfmodex.dylib $(TARGET).app/Contents/MacOS/$(BIN_NAME)
+ @echo
+ @echo " compiling done"
+ @echo " to launch the application"
+ @echo
+ @echo " open $(TARGET).app"
+ @echo
+
+
+.PHONY: help
+help:
+ @echo
+ @echo openFrameworks universal makefile
+ @echo
+ @echo targets:
+ @echo "make Debug: builds the application with debug symbols"
+ @echo "make Release: builds the app with optimizations"
+ @echo "make: = make Release"
+ @echo "make all: = make Release"
+ @echo "make CleanDebug: cleans the Debug target"
+ @echo "make CleanRelease: cleans the Release target"
+ @echo "make clean: cleans everything"
+ @echo
+ @echo this should work with any OF app, just copy any example
+ @echo change the name of the folder and it should compile
+ @echo "only .cpp support, don't use .c files"
+ @echo it will look for files in any folder inside the application
+ @echo folder except that in the EXCLUDE_FROM_SOURCE variable.
+ @echo "it doesn't autodetect include paths yet"
+ @echo "add the include paths editing the var USER_CFLAGS"
+ @echo at the beginning of the makefile using the gcc syntax:
+ @echo -Ipath
+ @echo
+ @echo to add addons to your application, edit the addons.make file
+ @echo in this directory and add the names of the addons you want to
+ @echo include
+ @echo
diff --git a/06_performance/addons.make b/06_performance/addons.make
new file mode 100755
index 0000000..cd4c2cc
--- /dev/null
+++ b/06_performance/addons.make
@@ -0,0 +1,3 @@
+ofxXmlSettings
+ofxMidi
+
diff --git a/06_performance/config.mak b/06_performance/config.mak
new file mode 100755
index 0000000..caf7203
--- /dev/null
+++ b/06_performance/config.mak
@@ -0,0 +1,56 @@
+# add custom variables to this file
+
+# OF_ROOT allows to move projects outside apps/* just set this variable to the
+# absoulte path to the OF root folder
+
+OF_ROOT = ../../../../../
+
+
+# USER_CFLAGS allows to pass custom flags to the compiler
+# for example search paths like:
+# USER_CFLAGS = -I src/objects
+
+#USER_CFLAGS = -I $(OF_ROOT)/addons/ofxOpenNI/include/openni -I $(OF_ROOT)/addons/ofxOpenNI/include/nite -I $(OF_ROOT)/addons/ofxOpenNI/src
+
+
+# USER_LDFLAGS allows to pass custom flags to the linker
+# for example libraries like:
+# USER_LDFLAGS = libs/libawesomelib.a
+
+#USER_LDFLAGS = -lOpenNI
+#USER_LDFLAGS = -L bin/data/openni/lib -L ../../../data/openni/lib/libusb-1.0.0.dylib -lOpenNI
+
+EXCLUDE_FROM_SOURCE="bin,.xcodeproj,obj"
+
+# change this to add different compiler optimizations to your project
+
+USER_COMPILER_OPTIMIZATION = -march=native -mtune=native -Os
+
+
+# android specific, in case you want to use different optimizations
+USER_LIBS_ARM =
+USER_LIBS_ARM7 =
+USER_LIBS_NEON =
+
+# android optimizations
+
+ANDROID_COMPILER_OPTIMIZATION = -Os
+
+NDK_PLATFORM = android-8
+
+# uncomment this for custom application name (if the folder name is different than the application name)
+#APPNAME = folderName
+
+# uncomment this for custom package name, must be the same as the java package that contains OFActivity
+#PKGNAME = cc.openframeworks.$(APPNAME)
+
+
+
+
+
+# linux arm flags
+
+LINUX_ARM7_COMPILER_OPTIMIZATIONS = -march=armv7-a -mtune=cortex-a8 -finline-functions -funroll-all-loops -O3 -funsafe-math-optimizations -mfpu=neon -ftree-vectorize -mfloat-abi=hard -mfpu=vfp
+
+
+
diff --git a/06_performance/config.make b/06_performance/config.make
new file mode 100644
index 0000000..261aa2e
--- /dev/null
+++ b/06_performance/config.make
@@ -0,0 +1,56 @@
+# add custom variables to this file
+
+# OF_ROOT allows to move projects outside apps/* just set this variable to the
+# absoulte path to the OF root folder
+
+OF_ROOT = ../openFrameworks
+
+
+# USER_CFLAGS allows to pass custom flags to the compiler
+# for example search paths like:
+# USER_CFLAGS = -I src/objects
+
+USER_CFLAGS = -I $(OF_ROOT)/addons/ofxOpenNI/include/openni -I $(OF_ROOT)/addons/ofxOpenNI/include/nite -I $(OF_ROOT)/addons/ofxOpenNI/src
+
+
+# USER_LDFLAGS allows to pass custom flags to the linker
+# for example libraries like:
+# USER_LDFLAGS = libs/libawesomelib.a
+
+USER_LDFLAGS = -lusb-1.0
+
+
+EXCLUDE_FROM_SOURCE="bin,.xcodeproj,obj"
+
+# change this to add different compiler optimizations to your project
+
+USER_COMPILER_OPTIMIZATION = -march=native -mtune=native -Os
+
+
+# android specific, in case you want to use different optimizations
+USER_LIBS_ARM =
+USER_LIBS_ARM7 =
+USER_LIBS_NEON =
+
+# android optimizations
+
+ANDROID_COMPILER_OPTIMIZATION = -Os
+
+NDK_PLATFORM = android-8
+
+# uncomment this for custom application name (if the folder name is different than the application name)
+#APPNAME = folderName
+
+# uncomment this for custom package name, must be the same as the java package that contains OFActivity
+#PKGNAME = cc.openframeworks.$(APPNAME)
+
+
+
+
+
+# linux arm flags
+
+LINUX_ARM7_COMPILER_OPTIMIZATIONS = -march=armv7-a -mtune=cortex-a8 -finline-functions -funroll-all-loops -O3 -funsafe-math-optimizations -mfpu=neon -ftree-vectorize -mfloat-abi=hard -mfpu=vfp
+
+
+
diff --git a/06_performance/src/FFTOctaveAnalyzer.cpp b/06_performance/src/FFTOctaveAnalyzer.cpp
new file mode 100644
index 0000000..4c91eeb
--- /dev/null
+++ b/06_performance/src/FFTOctaveAnalyzer.cpp
@@ -0,0 +1,98 @@
+#include "ofMain.h"
+#include "FFTOctaveAnalyzer.h"
+
+
+void FFTOctaveAnalyzer::setup(float samplingRate, int nBandsInTheFFT, int nAveragesPerOctave){
+
+ samplingRate = samplingRate;
+ nSpectrum = nBandsInTheFFT;
+ spectrumFrequencySpan = (samplingRate / 2.0f) / (float)(nSpectrum);
+ nAverages = nBandsInTheFFT;
+ // fe: 2f for octave bands, sqrt(2) for half-octave bands, cuberoot(2) for third-octave bands, etc
+ if (nAveragesPerOctave==0) // um, wtf?
+ nAveragesPerOctave = 1;
+ nAveragesPerOctave = nAveragesPerOctave;
+ averageFrequencyIncrement = pow(2.0f, 1.0f/(float)(nAveragesPerOctave));
+ // this isn't currently configurable (used once here then no effect), but here's some reasoning:
+ // 43 is a good value if you want to approximate "computer" octaves: 44100/2/2/2/2/2/2/2/2/2/2
+ // 55 is a good value if you'd rather approximate A-440 octaves: 440/2/2/2
+ // 65 is a good value if you'd rather approximate "middle-C" octaves: ~262/2/2
+ // you could easily double it if you felt the lowest band was just rumble noise (as it probably is)
+ // but don't go much smaller unless you have a huge fft window size (see below for more why)
+ // keep in mind, if you change it, that the number of actual bands may change +/-1, and
+ // for some values, the last averaging band may not be very useful (may extend above nyquist)
+ firstOctaveFrequency = 55.0f;
+ // for each spectrum[] bin, calculate the mapping into the appropriate average[] bin.
+ // this gives us roughly log-sized averaging bins, subject to how "fine" the spectrum bins are.
+ // with more spectrum bins, you can better map into the averaging bins (especially at low
+ // frequencies) or use more averaging bins per octave. with an fft window size of 2048,
+ // sampling rate of 44100, and first octave around 55, that's about enough to do half-octave
+ // analysis. if you don't have enough spectrum bins to map adequately into averaging bins
+ // at the requested number per octave then you'll end up with "empty" averaging bins, where
+ // there is no spectrum available to map into it. (so... if you have "nonreactive" averages,
+ // either increase fft buffer size, or decrease number of averages per octave, etc)
+ spe2avg = new int[nSpectrum];
+ int avgidx = 0;
+ float averageFreq = firstOctaveFrequency; // the "top" of the first averaging bin
+ // we're looking for the "top" of the first spectrum bin, and i'm just sort of
+ // guessing that this is where it is (or possibly spectrumFrequencySpan/2?)
+ // ... either way it's probably close enough for these purposes
+ float spectrumFreq = spectrumFrequencySpan;
+ for (int speidx=0; speidx < nSpectrum; speidx++) {
+ while (spectrumFreq > averageFreq) {
+ avgidx++;
+ averageFreq *= averageFrequencyIncrement;
+ }
+ spe2avg[speidx] = avgidx;
+ spectrumFreq += spectrumFrequencySpan;
+ }
+ nAverages = avgidx;
+ averages = new float[nAverages];
+ peaks = new float[nAverages];
+ peakHoldTimes = new int[nAverages];
+ peakHoldTime = 0; // arbitrary
+ peakDecayRate = 0.9f; // arbitrary
+ linearEQIntercept = 1.0f; // unity -- no eq by default
+ linearEQSlope = 0.0f; // unity -- no eq by default
+}
+
+void FFTOctaveAnalyzer::calculate(float * fftData){
+
+ int last_avgidx = 0; // tracks when we've crossed into a new averaging bin, so store current average
+ float sum = 0.0f; // running total of spectrum data
+ int count = 0; // count of spectrums accumulated (for averaging)
+ for (int speidx=0; speidx < nSpectrum; speidx++) {
+ count++;
+ sum += fftData[speidx] * (linearEQIntercept + (float)(speidx) * linearEQSlope);
+ int avgidx = spe2avg[speidx];
+ if (avgidx != last_avgidx) {
+
+ for (int j = last_avgidx; j < avgidx; j++){
+ averages[j] = sum / (float)(count);
+ }
+ count = 0;
+ sum = 0.0f;
+ }
+ last_avgidx = avgidx;
+ }
+ // the last average was probably not calculated...
+ if ((count > 0) && (last_avgidx < nAverages)){
+ averages[last_avgidx] = sum / (float)(count);
+ }
+
+ // update the peaks separately
+ for (int i=0; i < nAverages; i++) {
+ if (averages[i] >= peaks[i]) {
+ // save new peak level, also reset the hold timer
+ peaks[i] = averages[i];
+ peakHoldTimes[i] = peakHoldTime;
+ } else {
+ // current average does not exceed peak, so hold or decay the peak
+ if (peakHoldTimes[i] > 0) {
+ peakHoldTimes[i]--;
+ } else {
+ peaks[i] *= peakDecayRate;
+ }
+ }
+ }
+}
diff --git a/06_performance/src/FFTOctaveAnalyzer.h b/06_performance/src/FFTOctaveAnalyzer.h
new file mode 100644
index 0000000..8fef773
--- /dev/null
+++ b/06_performance/src/FFTOctaveAnalyzer.h
@@ -0,0 +1,45 @@
+
+#ifndef _FFTANALYZER
+#define _FFTANALYZER
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846 /* pi */
+#endif
+
+
+class FFTOctaveAnalyzer {
+
+public:
+
+ //FFT fft; // a reference to the FFT instance
+
+ float samplingRate; // sampling rate in Hz (needed to calculate frequency spans)
+ int nSpectrum; // number of spectrum bins in the fft
+ int nAverages; // number of averaging bins here
+ int nAveragesPerOctave; // number of averages per octave as requested by user
+ float spectrumFrequencySpan; // the "width" of an fft spectrum bin in Hz
+ float firstOctaveFrequency; // the "top" of the first averaging bin here in Hz
+ float averageFrequencyIncrement; // the root-of-two multiplier between averaging bin frequencies
+ float * averages; // the actual averages
+ float * peaks; // peaks of the averages, aka "maxAverages" in other implementations
+ int * peakHoldTimes; // how long to hold THIS peak meter? decay if == 0
+ int peakHoldTime; // how long do we hold peaks? (in fft frames)
+ float peakDecayRate; // how quickly the peaks decay: 0f=instantly .. 1f=not at all
+ int * spe2avg; // the mapping between spectrum[] indices and averages[] indices
+ // the fft's log equalizer() is no longer of any use (it would be nonsense to log scale
+ // the spectrum values into log-sized average bins) so here's a quick-and-dirty linear
+ // equalizer instead:
+ float linearEQSlope; // the rate of linear eq
+ float linearEQIntercept; // the base linear scaling used at the first averaging bin
+ // the formula is: spectrum[i] * (linearEQIntercept + i * linearEQSlope)
+ // so.. note that clever use of it can also provide a "gain" control of sorts
+ // (fe: set intercept to 2f and slope to 0f to double gain)
+
+ void setup(float samplingRate, int nBandsInTheFFT, int nAveragesPerOctave);
+
+ void calculate(float * fftData);
+
+};
+
+
+#endif
diff --git a/06_performance/src/fft.cpp b/06_performance/src/fft.cpp
new file mode 100644
index 0000000..ca3217e
--- /dev/null
+++ b/06_performance/src/fft.cpp
@@ -0,0 +1,489 @@
+/**********************************************************************
+
+ fft.cpp
+
+
+ This class is a C++ wrapper for original code
+ written by Dominic Mazzoni in September 2000
+
+ This file contains a few FFT routines, including a real-FFT
+ routine that is almost twice as fast as a normal complex FFT,
+ and a power spectrum routine which is more convenient when
+ you know you don't care about phase information. It now also
+ contains a few basic windowing functions.
+
+ Some of this code was based on a free implementation of an FFT
+ by Don Cross, available on the web at:
+
+ http://www.intersrv.com/~dcross/fft.html
+
+ The basic algorithm for his code was based on Numerical Recipes
+ in Fortran. I optimized his code further by reducing array
+ accesses, caching the bit reversal table, and eliminating
+ float-to-double conversions, and I added the routines to
+ calculate a real FFT and a real power spectrum.
+
+ Note: all of these routines use single-precision floats.
+ I have found that in practice, floats work well until you
+ get above 8192 samples. If you need to do a larger FFT,
+ you need to use doubles.
+
+**********************************************************************/
+
+#include "fft.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+int **gFFTBitTable = NULL;
+const int MaxFastBits = 16;
+
+int IsPowerOfTwo(int x)
+{
+ if (x < 2)
+ return false;
+
+ if (x & (x - 1)) /* Thanks to 'byang' for this cute trick! */
+ return false;
+
+ return true;
+}
+
+int NumberOfBitsNeeded(int PowerOfTwo)
+{
+ int i;
+
+ if (PowerOfTwo < 2) {
+ fprintf(stderr, "Error: FFT called with size %d\n", PowerOfTwo);
+ exit(1);
+ }
+
+ for (i = 0;; i++)
+ if (PowerOfTwo & (1 << i))
+ return i;
+}
+
+int ReverseBits(int index, int NumBits)
+{
+ int i, rev;
+
+ for (i = rev = 0; i < NumBits; i++) {
+ rev = (rev << 1) | (index & 1);
+ index >>= 1;
+ }
+
+ return rev;
+}
+
+void InitFFT()
+{
+ gFFTBitTable = new int *[MaxFastBits];
+
+ int len = 2;
+ for (int b = 1; b <= MaxFastBits; b++) {
+
+ gFFTBitTable[b - 1] = new int[len];
+
+ for (int i = 0; i < len; i++)
+ gFFTBitTable[b - 1][i] = ReverseBits(i, b);
+
+ len <<= 1;
+ }
+}
+
+inline int FastReverseBits(int i, int NumBits)
+{
+ if (NumBits <= MaxFastBits)
+ return gFFTBitTable[NumBits - 1][i];
+ else
+ return ReverseBits(i, NumBits);
+}
+
+/*
+ * Complex Fast Fourier Transform
+ */
+
+void FFT(int NumSamples,
+ bool InverseTransform,
+ float *RealIn, float *ImagIn, float *RealOut, float *ImagOut)
+{
+ int NumBits; /* Number of bits needed to store indices */
+ int i, j, k, n;
+ int BlockSize, BlockEnd;
+
+ double angle_numerator = 2.0 * M_PI;
+ float tr, ti; /* temp real, temp imaginary */
+
+ if (!IsPowerOfTwo(NumSamples)) {
+ fprintf(stderr, "%d is not a power of two\n", NumSamples);
+ exit(1);
+ }
+
+ if (!gFFTBitTable)
+ InitFFT();
+
+ if (InverseTransform)
+ angle_numerator = -angle_numerator;
+
+ NumBits = NumberOfBitsNeeded(NumSamples);
+
+ /*
+ ** Do simultaneous data copy and bit-reversal ordering into outputs...
+ */
+
+ for (i = 0; i < NumSamples; i++) {
+ j = FastReverseBits(i, NumBits);
+ RealOut[j] = RealIn[i];
+ ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
+ }
+
+ /*
+ ** Do the FFT itself...
+ */
+
+ BlockEnd = 1;
+ for (BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1) {
+
+ double delta_angle = angle_numerator / (double) BlockSize;
+
+ float sm2 = sin(-2 * delta_angle);
+ float sm1 = sin(-delta_angle);
+ float cm2 = cos(-2 * delta_angle);
+ float cm1 = cos(-delta_angle);
+ float w = 2 * cm1;
+ float ar0, ar1, ar2, ai0, ai1, ai2;
+
+ for (i = 0; i < NumSamples; i += BlockSize) {
+ ar2 = cm2;
+ ar1 = cm1;
+
+ ai2 = sm2;
+ ai1 = sm1;
+
+ for (j = i, n = 0; n < BlockEnd; j++, n++) {
+ ar0 = w * ar1 - ar2;
+ ar2 = ar1;
+ ar1 = ar0;
+
+ ai0 = w * ai1 - ai2;
+ ai2 = ai1;
+ ai1 = ai0;
+
+ k = j + BlockEnd;
+ tr = ar0 * RealOut[k] - ai0 * ImagOut[k];
+ ti = ar0 * ImagOut[k] + ai0 * RealOut[k];
+
+ RealOut[k] = RealOut[j] - tr;
+ ImagOut[k] = ImagOut[j] - ti;
+
+ RealOut[j] += tr;
+ ImagOut[j] += ti;
+ }
+ }
+
+ BlockEnd = BlockSize;
+ }
+
+ /*
+ ** Need to normalize if inverse transform...
+ */
+
+ if (InverseTransform) {
+ float denom = (float) NumSamples;
+
+ for (i = 0; i < NumSamples; i++) {
+ RealOut[i] /= denom;
+ ImagOut[i] /= denom;
+ }
+ }
+}
+
+/*
+ * Real Fast Fourier Transform
+ *
+ * This function was based on the code in Numerical Recipes in C.
+ * In Num. Rec., the inner loop is based on a single 1-based array
+ * of interleaved real and imaginary numbers. Because we have two
+ * separate zero-based arrays, our indices are quite different.
+ * Here is the correspondence between Num. Rec. indices and our indices:
+ *
+ * i1 <-> real[i]
+ * i2 <-> imag[i]
+ * i3 <-> real[n/2-i]
+ * i4 <-> imag[n/2-i]
+ */
+
+void RealFFT(int NumSamples, float *RealIn, float *RealOut, float *ImagOut)
+{
+ int Half = NumSamples / 2;
+ int i;
+
+ float theta = M_PI / Half;
+
+ float *tmpReal = new float[Half];
+ float *tmpImag = new float[Half];
+
+ for (i = 0; i < Half; i++) {
+ tmpReal[i] = RealIn[2 * i];
+ tmpImag[i] = RealIn[2 * i + 1];
+ }
+
+ FFT(Half, 0, tmpReal, tmpImag, RealOut, ImagOut);
+
+ float wtemp = float (sin(0.5 * theta));
+
+ float wpr = -2.0 * wtemp * wtemp;
+ float wpi = float (sin(theta));
+ float wr = 1.0 + wpr;
+ float wi = wpi;
+
+ int i3;
+
+ float h1r, h1i, h2r, h2i;
+
+ for (i = 1; i < Half / 2; i++) {
+
+ i3 = Half - i;
+
+ h1r = 0.5 * (RealOut[i] + RealOut[i3]);
+ h1i = 0.5 * (ImagOut[i] - ImagOut[i3]);
+ h2r = 0.5 * (ImagOut[i] + ImagOut[i3]);
+ h2i = -0.5 * (RealOut[i] - RealOut[i3]);
+
+ RealOut[i] = h1r + wr * h2r - wi * h2i;
+ ImagOut[i] = h1i + wr * h2i + wi * h2r;
+ RealOut[i3] = h1r - wr * h2r + wi * h2i;
+ ImagOut[i3] = -h1i + wr * h2i + wi * h2r;
+
+ wr = (wtemp = wr) * wpr - wi * wpi + wr;
+ wi = wi * wpr + wtemp * wpi + wi;
+ }
+
+ RealOut[0] = (h1r = RealOut[0]) + ImagOut[0];
+ ImagOut[0] = h1r - ImagOut[0];
+
+ delete[]tmpReal;
+ delete[]tmpImag;
+}
+
+/*
+ * PowerSpectrum
+ *
+ * This function computes the same as RealFFT, above, but
+ * adds the squares of the real and imaginary part of each
+ * coefficient, extracting the power and throwing away the
+ * phase.
+ *
+ * For speed, it does not call RealFFT, but duplicates some
+ * of its code.
+ */
+
+void PowerSpectrum(int NumSamples, float *In, float *Out)
+{
+ int Half = NumSamples / 2;
+ int i;
+
+ float theta = M_PI / Half;
+
+ float *tmpReal = new float[Half];
+ float *tmpImag = new float[Half];
+ float *RealOut = new float[Half];
+ float *ImagOut = new float[Half];
+
+ for (i = 0; i < Half; i++) {
+ tmpReal[i] = In[2 * i];
+ tmpImag[i] = In[2 * i + 1];
+ }
+
+ FFT(Half, 0, tmpReal, tmpImag, RealOut, ImagOut);
+
+ float wtemp = float (sin(0.5 * theta));
+
+ float wpr = -2.0 * wtemp * wtemp;
+ float wpi = float (sin(theta));
+ float wr = 1.0 + wpr;
+ float wi = wpi;
+
+ int i3;
+
+ float h1r, h1i, h2r, h2i, rt, it;
+ //float total=0;
+
+ for (i = 1; i < Half / 2; i++) {
+
+ i3 = Half - i;
+
+ h1r = 0.5 * (RealOut[i] + RealOut[i3]);
+ h1i = 0.5 * (ImagOut[i] - ImagOut[i3]);
+ h2r = 0.5 * (ImagOut[i] + ImagOut[i3]);
+ h2i = -0.5 * (RealOut[i] - RealOut[i3]);
+
+ rt = h1r + wr * h2r - wi * h2i; //printf("Realout%i = %f",i,rt);total+=fabs(rt);
+ it = h1i + wr * h2i + wi * h2r; // printf(" Imageout%i = %f\n",i,it);
+
+ Out[i] = rt * rt + it * it;
+
+ rt = h1r - wr * h2r + wi * h2i;
+ it = -h1i + wr * h2i + wi * h2r;
+
+ Out[i3] = rt * rt + it * it;
+
+ wr = (wtemp = wr) * wpr - wi * wpi + wr;
+ wi = wi * wpr + wtemp * wpi + wi;
+ }
+ //printf("total = %f\n",total);
+ rt = (h1r = RealOut[0]) + ImagOut[0];
+ it = h1r - ImagOut[0];
+ Out[0] = rt * rt + it * it;
+
+ rt = RealOut[Half / 2];
+ it = ImagOut[Half / 2];
+ Out[Half / 2] = rt * rt + it * it;
+
+ delete[]tmpReal;
+ delete[]tmpImag;
+ delete[]RealOut;
+ delete[]ImagOut;
+}
+
+/*
+ * Windowing Functions
+ */
+
+int NumWindowFuncs()
+{
+ return 4;
+}
+
+char *WindowFuncName(int whichFunction)
+{
+ switch (whichFunction) {
+ default:
+ case 0:
+ return "Rectangular";
+ case 1:
+ return "Bartlett";
+ case 2:
+ return "Hamming";
+ case 3:
+ return "Hanning";
+ }
+}
+
+void WindowFunc(int whichFunction, int NumSamples, float *in)
+{
+ int i;
+
+ if (whichFunction == 1) {
+ // Bartlett (triangular) window
+ for (i = 0; i < NumSamples / 2; i++) {
+ in[i] *= (i / (float) (NumSamples / 2));
+ in[i + (NumSamples / 2)] *=
+ (1.0 - (i / (float) (NumSamples / 2)));
+ }
+ }
+
+ if (whichFunction == 2) {
+ // Hamming
+ for (i = 0; i < NumSamples; i++)
+ in[i] *= 0.54 - 0.46 * cos(2 * M_PI * i / (NumSamples - 1));
+ }
+
+ if (whichFunction == 3) {
+ // Hanning
+ for (i = 0; i < NumSamples; i++)
+ in[i] *= 0.50 - 0.50 * cos(2 * M_PI * i / (NumSamples - 1));
+ }
+}
+
+/* constructor */
+fft::fft() {
+}
+
+/* destructor */
+fft::~fft() {
+
+
+}
+
+/* Calculate the power spectrum */
+void fft::powerSpectrum(int start, int half, float *data, int windowSize,float *magnitude,float *phase, float *power, float *avg_power) {
+ int i;
+ int windowFunc = 3;
+ float total_power = 0.0f;
+
+ /* processing variables*/
+ float *in_real = new float[windowSize];
+ float *in_img = new float[windowSize];
+ float *out_real = new float[windowSize];
+ float *out_img = new float[windowSize];
+
+ for (i = 0; i < windowSize; i++) {
+ in_real[i] = data[start + i];
+ }
+
+ WindowFunc(windowFunc, windowSize, in_real);
+ RealFFT(windowSize, in_real, out_real, out_img);
+
+ for (i = 0; i < half; i++) {
+ /* compute power */
+ power[i] = out_real[i]*out_real[i] + out_img[i]*out_img[i];
+ total_power += power[i];
+ /* compute magnitude and phase */
+ magnitude[i] = 2.0*sqrt(power[i]);
+
+ if (magnitude[i] < 0.000001){ // less than 0.1 nV
+ magnitude[i] = 0; // out of range
+ } else {
+ magnitude[i] = 20.0*log10(magnitude[i] + 1); // get to to db scale
+ }
+
+
+ phase[i] = atan2(out_img[i],out_real[i]);
+ }
+ /* calculate average power */
+ *(avg_power) = total_power / (float) half;
+
+ delete[]in_real;
+ delete[]in_img;
+ delete[]out_real;
+ delete[]out_img;
+}
+
+
+void fft::inversePowerSpectrum(int start, int half, int windowSize, float *finalOut,float *magnitude,float *phase) {
+ int i;
+ int windowFunc = 3;
+
+ /* processing variables*/
+ float *in_real = new float[windowSize];
+ float *in_img = new float[windowSize];
+ float *out_real = new float[windowSize];
+ float *out_img = new float[windowSize];
+
+ /* get real and imag part */
+ for (i = 0; i < half; i++) {
+ in_real[i] = magnitude[i]*cos(phase[i]);
+ in_img[i] = magnitude[i]*sin(phase[i]);
+ }
+
+ /* zero negative frequencies */
+ for (i = half; i < windowSize; i++) {
+ in_real[i] = 0.0;
+ in_img[i] = 0.0;
+ }
+
+ FFT(windowSize, 1, in_real, in_img, out_real, out_img); // second parameter indicates inverse transform
+ WindowFunc(windowFunc, windowSize, out_real);
+
+ for (i = 0; i < windowSize; i++) {
+ finalOut[start + i] += out_real[i];
+ }
+
+ delete[]in_real;
+ delete[]in_img;
+ delete[]out_real;
+ delete[]out_img;
+}
+
+
diff --git a/06_performance/src/fft.h b/06_performance/src/fft.h
new file mode 100644
index 0000000..bae5b37
--- /dev/null
+++ b/06_performance/src/fft.h
@@ -0,0 +1,33 @@
+
+#ifndef _FFT
+#define _FFT
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846 /* pi */
+#endif
+
+
+class fft {
+
+ public:
+
+ fft();
+ ~fft();
+
+ /* Calculate the power spectrum */
+ void powerSpectrum(int start, int half, float *data, int windowSize,float *magnitude,float *phase, float *power, float *avg_power);
+ /* ... the inverse */
+ void inversePowerSpectrum(int start, int half, int windowSize, float *finalOut,float *magnitude,float *phase);
+
+ void processLogXScale(const float * data,unsigned int insize, double fMax,
+ float * avout, float * pkout, unsigned int outsize,
+ float f1, float f2);
+
+
+ float avout[15];
+ float pkout[15];
+
+};
+
+
+#endif
diff --git a/06_performance/src/main.cpp b/06_performance/src/main.cpp
new file mode 100644
index 0000000..58263a2
--- /dev/null
+++ b/06_performance/src/main.cpp
@@ -0,0 +1,17 @@
+#include "ofMain.h"
+#include "testApp.h"
+
+//========================================================================
+int main( ){
+
+ ofSetupOpenGL(4080,768, OF_WINDOW); // <-------- setup the GL context
+
+
+
+ // 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/06_performance/src/oni.cpp b/06_performance/src/oni.cpp
new file mode 100644
index 0000000..a202f41
--- /dev/null
+++ b/06_performance/src/oni.cpp
@@ -0,0 +1 @@
+#include "oni.h" \ No newline at end of file
diff --git a/06_performance/src/oni.h b/06_performance/src/oni.h
new file mode 100644
index 0000000..ccb1417
--- /dev/null
+++ b/06_performance/src/oni.h
@@ -0,0 +1 @@
+#include "ofxOpenNI.h" \ No newline at end of file
diff --git a/06_performance/src/testApp.cpp b/06_performance/src/testApp.cpp
new file mode 100644
index 0000000..d41071a
--- /dev/null
+++ b/06_performance/src/testApp.cpp
@@ -0,0 +1,776 @@
+#include "testApp.h"
+
+ /*
+ maybe draw pixel lines to a range of buffers and then play them in various 3D directions
+ pixel lines can have nice, missing corners and be nicely smoothed
+
+ is it insane not to do this in vvvv
+
+ can there be an editing interface
+
+ have a play with vvvv/ max and try to replicate this idea QUICKLY?
+ */
+
+
+//--------------------------------------------------------------
+void testApp::setup(){
+
+ midiIn.listPorts();
+
+ midiIn.openPort(0); //this was 1 on linux
+ midiIn.addListener(this);
+
+ midiOut.listPorts();
+ midiOut.openPort(0); //this was 1 on linux
+
+ // 0 output channeLs,
+ // 2 input channels
+ // 44100 samples per second
+ // BUFFER_SIZE samples per buffer
+ // 4 num buffers (latency)
+
+ soundStream.listDevices();
+
+ left = new float[BUFFER_SIZE];
+ right = new float[BUFFER_SIZE];
+
+ soundStream.setDeviceID(0);
+ soundStream.setup(this, 0, 2, 44100, BUFFER_SIZE, 4);
+
+ ofSetHexColor(0x666666);
+
+ lFFTanalyzer.setup(44100, BUFFER_SIZE/2,32);
+
+ lFFTanalyzer.peakHoldTime = 15; // hold longer
+ lFFTanalyzer.peakDecayRate = 0.95f; // decay slower
+ lFFTanalyzer.linearEQIntercept = 0.9f; // reduced gain at lowest frequency
+ lFFTanalyzer.linearEQSlope = 0.01f; // increasing gain at higher frequencies
+
+ rFFTanalyzer.setup(44100, BUFFER_SIZE/2,32);
+
+ rFFTanalyzer.peakHoldTime = 15; // hold longer
+ rFFTanalyzer.peakDecayRate = 0.95f; // decay slower
+ rFFTanalyzer.linearEQIntercept = 0.9f; // reduced gain at lowest frequency
+ rFFTanalyzer.linearEQSlope = 0.01f; // increasing gain at higher frequencies
+
+ ofSetFrameRate(60);
+
+ ofBackground(0,0,0);
+
+ F_movieSpeed=0.0;
+
+ //blendImage.loadImage("blend01.png");
+ blendImage.loadMovie("blend01.mov");
+ blendImage.play();
+ blendImage.setLoopState(OF_LOOP_NORMAL);
+ blendImage.setSpeed(F_movieSpeed);
+
+ I_movieSource=0;
+ I_moviePlaying=0;
+
+ renderImage.allocate(ofGetWidth(),ofGetHeight(),GL_RGB);
+ maskShader.load("composite");
+
+ //testImage.loadImage("mask.png");
+
+
+ maskShader.begin();
+ maskShader.setUniformTexture("Tex0", blendImage.getTextureReference(), 0);
+ maskShader.setUniformTexture("Tex1", renderImage.getTextureReference(), 1);
+ maskShader.end();
+
+ showFPS=false;
+
+ //defaults
+
+ F_scale=0;
+ F_drawFrames=10;
+ F_drawStep=0;
+ F_drawDecay=0.95;
+ F_lineWidth=1.0;
+ F_drawAxis=90; //Y
+
+
+ F_xRotate=0;
+ F_yRotate=0;
+ F_zRotate=0;
+
+ F_xRotation=0;
+ F_yRotation=180;
+ F_zRotation=0;
+
+ F_particleAmount=100;
+ F_particleLife=0.5;
+
+ I_fade1=0;
+ I_fade2=0;
+
+ thisFFTbuffer=0;
+
+ lastFrameTime=ofGetElapsedTimef();
+
+ draworder=true; //forwards;
+
+ visMode=WAVEFORM;
+
+ B_vSync=true;
+ B_fill=true;
+
+ inputMode=PICTURE;
+
+
+ gammamap=new unsigned char[256];
+
+
+ whitePt=0.9;
+ blackPt=0.3;
+ gamma=1.0;
+
+ //calc gamma map
+ for (int i=0;i<256;i++){
+ 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);
+ }
+
+ B_glitch=false;
+
+ blanker.allocate(64,64,OF_IMAGE_COLOR);
+ // blanker.loadImage("black.png");
+
+
+ fullScreen=false;
+
+ setMidiState();
+}
+
+
+
+//--------------------------------------------------------------
+void testApp::update(){
+
+
+ if (I_movieSource!=I_moviePlaying) {
+ blendImage.stop();
+ switch(I_movieSource){
+ case 0:
+ blendImage.loadMovie("gradblend.mov");
+ break;
+ case 1:
+ blendImage.loadMovie("gradblend01.mov");
+ break;
+ case 2:
+ blendImage.loadMovie("ll_waltz1.mov");
+ break;
+ case 3:
+ blendImage.loadMovie("ll_longtrains.avi");
+ break;
+
+ }
+ blendImage.play();
+ blendImage.setLoopState(OF_LOOP_NORMAL);
+ I_moviePlaying=I_movieSource;
+ }
+ blendImage.setSpeed(F_movieSpeed);
+ blendImage.idleMovie();
+}
+
+//--------------------------------------------------------------
+void testApp::draw(){
+ ofSetVerticalSync(B_vSync);
+
+ static int index=0;
+ float lavg_power = 0.0f;
+ float ravg_power = 0.0f;
+
+ if (visMode==FFT_RAW||visMode==FFT_AVG) {
+ myfft.powerSpectrum(0,(int)BUFFER_SIZE/2, left,BUFFER_SIZE,&lmagnitude[0],&lphase[0],&lpower[0],&lavg_power);
+ myfft.powerSpectrum(0,(int)BUFFER_SIZE/2, right,BUFFER_SIZE,&rmagnitude[0],&rphase[0],&rpower[0],&ravg_power);
+ }
+ if (visMode==FFT_AVG) {
+ lFFTanalyzer.calculate(lmagnitude);
+ rFFTanalyzer.calculate(rmagnitude);
+ }
+
+ thisFFTbuffer=(thisFFTbuffer-1);
+ thisFFTbuffer=thisFFTbuffer<0?BUFFER_FRAMES-1:thisFFTbuffer;
+
+ switch(visMode) {
+ case FFT_AVG:
+ for (int i=0;i<rFFTanalyzer.nAverages;i++) {
+ FFTbuffer[0][i][thisFFTbuffer]=lFFTanalyzer.averages[i];
+ FFTbuffer[1][i][thisFFTbuffer]=rFFTanalyzer.averages[i];
+ }
+ break;
+ case FFT_RAW:
+ for (int i=0;i<BUFFER_SIZE;i++) {
+ FFTbuffer[0][i][thisFFTbuffer]=lmagnitude[i]*3;
+ FFTbuffer[1][i][thisFFTbuffer]=rmagnitude[i]*3;
+ }
+ break;
+ case WAVEFORM:
+ for (int i=0;i<BUFFER_SIZE/2;i++) {
+ FFTbuffer[0][i][thisFFTbuffer]=left[i]*100;
+ FFTbuffer[1][i][thisFFTbuffer]=right[i]*100;
+ }
+ break;
+ }
+
+ //ofDisableAlphaBlending();
+
+ renderImage.begin(); //render to FOB
+ glDisable(GL_BLEND);
+
+ float hw=ofGetWidth()/2;
+ float hh=ofGetHeight()/2;
+ float xStep = ((float)ofGetWidth())/(lFFTanalyzer.nAverages*2);
+ float zStep = ((float)ofGetWidth())/F_drawFrames;
+
+ float newTime=ofGetElapsedTimef();
+ float interval=newTime-lastFrameTime;
+ lastFrameTime=newTime;
+
+
+ if (B_glitch) {
+ //glEnable(GL_BLEND);
+ //glBlendFunc(GL_CONSTANT_COLOR,GL_ONE);
+ //glBlendColor(1.0f,1.0f,1.0f,0.9f);
+ //blanker.draw(0,0,ofGetWidth(),ofGetHeight());
+ }
+ else {
+ glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
+ }
+
+
+ F_xRotation+=(F_xRotate*interval);
+ F_yRotation+=(F_yRotate*interval);
+ F_zRotation+=(F_zRotate*interval);
+ F_drawFrames=max(1.99f,min(F_drawFrames+(F_drawStep*interval),(float)BUFFER_FRAMES));
+
+ ofPushMatrix();
+ ofTranslate(hw,hh);
+ ofRotateX(F_xRotation);
+ ofRotateY(F_yRotation);
+ ofRotateZ(F_zRotation);
+
+
+ if (inputMode==GRABBER) {
+ ofSetColor(I_fade2,I_fade2,I_fade2);
+ ofPushMatrix();
+ ofRotateX(90);
+ ofRotateZ(-90);
+ outTexture.draw(hw,-hh,-ofGetWidth(),ofGetHeight());
+ ofPopMatrix();
+ }
+
+ GLfloat fogColor[4] = {0,0,0, 1.0};
+ glFogi(GL_FOG_MODE, GL_LINEAR);
+ glFogfv(GL_FOG_COLOR, fogColor);
+ glFogf(GL_FOG_DENSITY,1.0 );
+ glHint(GL_FOG_HINT, GL_DONT_CARE);
+ glFogf(GL_FOG_START, ofGetWidth()*(0.25+F_drawDecay));
+ glFogf(GL_FOG_END, ofGetWidth()*(0.75+F_drawDecay));
+ glEnable(GL_FOG);
+
+ //reverse draw order when looking from back
+ int jStart=0;
+ int jEnd=F_drawFrames-1;
+ int jStep=1;
+ float F_yseg=F_yRotation;
+ while (F_yseg<-90) F_yseg+=360;
+ while (F_yseg>270) F_yseg-=360;
+ if (F_yseg>90) {
+ jStart=jEnd;
+ jEnd=0;
+ jStep=-1;
+ if (draworder) {
+ draworder=false;
+ //printf("switched to reverse order\n");
+ }
+ }
+ else if (!draworder) {
+ draworder=true;
+ //printf("switched to normal order\n");
+ }
+
+ for (int j=jStart;j!=jEnd;j+=jStep) {
+ int fB=(thisFFTbuffer+j)%BUFFER_FRAMES;
+
+ ofPushMatrix(); //coordinate transform for FFT draw direction
+ ofTranslate(0,0,(j*zStep)-hw);
+ ofRotateX(F_drawAxis);
+
+ ofFill();
+ ofSetColor(0,0,0);
+ if (B_fill) {
+ glBegin(GL_QUAD_STRIP);
+ for (int i = 0; i < lFFTanalyzer.nAverages-1; i++){
+ glVertex3f((i*xStep)-hw,-(FFTbuffer[0][i][fB] * F_scale),0);
+ glVertex3f((i*xStep)-hw,0,0);
+ }
+ for (int i =lFFTanalyzer.nAverages, k=lFFTanalyzer.nAverages-1; i < lFFTanalyzer.nAverages+rFFTanalyzer.nAverages; i++, k--){
+ glVertex3f((i*xStep)-hw,-(FFTbuffer[1][(lFFTanalyzer.nAverages+rFFTanalyzer.nAverages)-(i+1)][fB] * F_scale),0);
+ glVertex3f((i*xStep)-hw,0,0);
+ }
+ glEnd();
+ }
+
+ ofNoFill();
+ ofSetLineWidth(F_lineWidth);
+ ofSetColor(I_fade1,I_fade1,I_fade1);
+ glBegin(GL_LINE_STRIP);
+ for (int i = 0; i < lFFTanalyzer.nAverages; i++){
+ glVertex3f((i*xStep)-hw,-(FFTbuffer[0][i][fB] * F_scale),0);
+ }
+ for (int i =lFFTanalyzer.nAverages, k=lFFTanalyzer.nAverages-1; i < lFFTanalyzer.nAverages+rFFTanalyzer.nAverages; i++, k--){
+ glVertex3f((i*xStep)-hw,-(FFTbuffer[1][(lFFTanalyzer.nAverages+rFFTanalyzer.nAverages)-(i+1)][fB] * F_scale),0);
+ }
+ glEnd();
+ ofPopMatrix();
+ }
+ ofPopMatrix();
+ renderImage.end();
+
+
+
+
+ //ofEndShape(false);
+
+
+ //fbImage.grabScreen(0,0,ofGetWidth(),ofGetHeight());
+/*
+
+
+
+
+ ofSetHexColor(0xaaaaaa);
+ int width=2048/FFTanalyzer.nAverages;
+ for (int i = 0; i < FFTanalyzer.nAverages; i++){
+ ofRect(i*width,768,width,-FFTanalyzer.averages[i] * 20);
+ }
+ ofSetHexColor(0xffffff);
+ for (int i = 0; i < (int)(BUFFER_SIZE/2 - 1); i++){
+ ofRect(i,768-freq[i]*10.0f,1,1);
+ }
+
+ ofSetHexColor(0xff0000);
+ for (int i = 0; i < FFTanalyzer.nAverages; i++){
+ ofRect(i*width,768-FFTanalyzer.peaks[i] * 20,width,-1);
+ }
+
+ float avgStep = 1024/FFTanalyzer.nAverages;
+
+
+ ofNoFill();
+ ofSetLineWidth(1);
+
+ ofSetColor(223, 218, 218);
+ ofDrawBitmapString("FFT average", 4, 18);
+ ofBeginShape();
+ for (int i = 0; i < FFTanalyzer.nAverages; i++){
+ ofVertex(i*avgStep, 284 -FFTanalyzer.averages[i] * 20);
+ }
+ ofEndShape(false);
+
+
+ ofSetColor(97,181,243);
+ ofDrawBitmapString("FFT magnitude", 4, 38);
+ ofBeginShape();
+ for (int i = 0; i < BUFFER_SIZE; i++){
+ ofVertex(i*avgStep, 384 -magnitude[i] * 20);
+ }
+ ofEndShape(false);
+
+
+ ofSetColor(97,243,174);
+ ofDrawBitmapString("FFT phase", 4, 58);
+ ofBeginShape();
+ for (int i = 0; i < BUFFER_SIZE; i++){
+ ofVertex(i*avgStep, 484 -phase[i] * 20);
+ }
+ ofEndShape(false);
+
+ ofSetColor(243,174,94);
+ ofDrawBitmapString("FFT power", 4, 78);
+ ofBeginShape();
+ for (int i = 0; i < BUFFER_SIZE; i++){
+ ofVertex(i*avgStep, 584 -power[i] * 20);
+ }
+ ofEndShape(false);
+
+
+ //float * averages; // the actual averages
+ //float * peaks; // peaks of the averages, aka "maxAverages" in other implementations
+
+*/
+
+ ofEnableAlphaBlending();
+
+ maskShader.begin();
+
+ glActiveTexture(GL_TEXTURE0_ARB);
+ blendImage.getTextureReference().bind();
+ glActiveTexture(GL_TEXTURE1_ARB);
+ renderImage.getTextureReference().bind();
+
+ glBegin(GL_QUADS);
+
+ glMultiTexCoord2d(GL_TEXTURE0_ARB, 0, 0);
+ glMultiTexCoord2d(GL_TEXTURE1_ARB, 0, 0);
+ glVertex2f( 0, 0);
+
+ glMultiTexCoord2d(GL_TEXTURE0_ARB, blendImage.getWidth(), 0);
+ glMultiTexCoord2d(GL_TEXTURE1_ARB, renderImage.getWidth(), 0);
+ glVertex2f( ofGetWidth(), 0);
+
+ glMultiTexCoord2d(GL_TEXTURE0_ARB, blendImage.getWidth(), blendImage.getHeight());
+ glMultiTexCoord2d(GL_TEXTURE1_ARB, renderImage.getWidth(), renderImage.getHeight() );
+ glVertex2f( ofGetWidth(), ofGetHeight());
+
+ glMultiTexCoord2d(GL_TEXTURE0_ARB, 0, blendImage.getHeight());
+ glMultiTexCoord2d(GL_TEXTURE1_ARB, 0, renderImage.getHeight() );
+ glVertex2f( 0, ofGetHeight() );
+
+ glEnd();
+
+ glActiveTexture(GL_TEXTURE1_ARB);
+ renderImage.getTextureReference().unbind();
+
+ glActiveTexture(GL_TEXTURE0_ARB);
+ blendImage.getTextureReference().unbind();
+
+ maskShader.end();
+/*
+ glPushMatrix();
+ glTranslatef(ofGetWidth()*0.5,ofGetHeight()*0.5,0);
+ glRotatef((float)ofGetFrameNum(),0,1.0,0);
+ renderImage.draw(ofGetWidth()*-0.5,ofGetHeight()*-0.5);
+ glPopMatrix();
+ */
+
+ if (showFPS) {
+ ofDrawBitmapString(ofToString(ofGetFrameRate(), 2),20,20);
+ ofDrawBitmapString(ofToString(F_xRotation, 4)+" "+ofToString(F_yRotation, 4)+" "+ofToString(F_zRotation, 4),20,30);
+ ofDrawBitmapString(ofToString(F_yseg, 4),20,40);
+ }
+}
+
+
+//--------------------------------------------------------------
+void testApp::keyPressed (int key){
+ if(key == 'f'){
+ showFPS=!showFPS;
+ }
+ if(key == ' '){
+ fullScreen=!fullScreen;
+ ofSetFullscreen(fullScreen);
+ }
+}
+
+//--------------------------------------------------------------
+void testApp::mouseMoved(int x, int y ){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseDragged(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mousePressed(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseReleased(){
+
+}
+
+
+//--------------------------------------------------------------
+void testApp::audioIn(float * input, int bufferSize, int nChannels){
+ /*if (sampnum<10) {
+ printf("size %i, channels %i\n",bufferSize,nChannels);
+ sampnum++;
+ }
+ */
+ // samples are "interleaved"
+ //if (nChannels==2) {
+ for (int i = 0; i < bufferSize; i++){
+ left[i] = input[i*2];
+ right[i] = input[i*2+1];
+ }
+ //}
+
+}
+
+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!
+
+ switch(eventArgs.status) {
+ case 144: //noteon-off
+
+ break;
+ case 176: //control change 1-8 x 4 banks
+ switch(eventArgs.byteOne) {
+ case 1:
+ F_scale = ((float)eventArgs.byteTwo)*.2;
+ break;
+ case 2:
+ F_lineWidth=(float)eventArgs.byteTwo*0.1;
+ break;
+ case 3:
+ F_drawAxis=((float) eventArgs.byteTwo-64)*(360.0/127);
+ break;
+ case 4:
+ F_particleAmount=((float) eventArgs.byteTwo)*(2000.0f/127.0f);
+ break;
+ case 5:
+ F_particleLife=((float) eventArgs.byteTwo)*(3.0f/127.0f);
+ break;
+ case 6:
+ F_particleX=(((float) eventArgs.byteTwo)-64)*.1f;
+ break;
+ case 7:
+ F_particleY=(((float) eventArgs.byteTwo)-64)*.1f;
+ break;
+ case 8:
+ F_particleZ=(((float) eventArgs.byteTwo)-64)*.1f;
+ break;
+
+ //65-80 buttons
+
+ //radio button set
+ case 65:
+ if (eventArgs.byteTwo==127) {
+ visMode=FFT_AVG;
+ midiOut.sendControlChange(1, 66, 0);
+ midiOut.sendControlChange(1, 67, 0);
+ }
+ else midiOut.sendControlChange(1, 65, 127);
+ break;
+ case 66:
+ if (eventArgs.byteTwo==127) {
+ visMode=FFT_RAW;
+ midiOut.sendControlChange(1, 65, 0);
+ midiOut.sendControlChange(1, 67, 0);
+ }
+ else midiOut.sendControlChange(1, 66, 127);
+ break;
+ case 67:
+ if (eventArgs.byteTwo==127) {
+ visMode=WAVEFORM;
+ midiOut.sendControlChange(1, 65, 0);
+ midiOut.sendControlChange(1, 66, 0);
+ }
+ else midiOut.sendControlChange(1, 67, 127);
+ break;
+
+ //radio button set
+ case 68:
+ if (eventArgs.byteTwo==127) {
+ inputMode=PICTURE;
+ midiOut.sendControlChange(1, 69, 0);
+
+ }
+ else midiOut.sendControlChange(1, 68, 127);
+ break;
+ case 69:
+ if (eventArgs.byteTwo==127) {
+ inputMode=GRABBER;
+ midiOut.sendControlChange(1, 68, 0);
+
+ }
+ else midiOut.sendControlChange(1, 69, 127);
+ break;
+ case 70:
+ B_glitch=(eventArgs.byteTwo==127);
+ break;
+ case 71:
+ B_fill=(eventArgs.byteTwo==127);
+ break;
+ case 72:
+ B_vSync=(eventArgs.byteTwo==127);
+ break;
+
+ //buttons to zero rotations
+ case 73:
+ F_xRotate=0;
+ midiOut.sendControlChange(1, 73, 0);
+ midiOut.sendControlChange(1, 81, 64);
+ break;
+ case 74:
+ F_yRotate=0;
+ midiOut.sendControlChange(1, 74, 0);
+ midiOut.sendControlChange(1, 82, 64);
+ break;
+ case 75:
+ F_zRotate=0;
+ midiOut.sendControlChange(1, 75, 0);
+ midiOut.sendControlChange(1, 83, 64);
+ break;
+ case 76:
+ F_drawStep=0;
+ midiOut.sendControlChange(1, 76, 0);
+ midiOut.sendControlChange(1, 84, 64);
+ break;
+ case 77:
+ if (eventArgs.byteTwo==127) {
+ I_movieSource=0;
+ midiOut.sendControlChange(1, 78, 0);
+ midiOut.sendControlChange(1, 79, 0);
+ midiOut.sendControlChange(1, 80, 0);
+
+ }
+ else midiOut.sendControlChange(1, 77, 127);
+ break;
+ case 78:
+ if (eventArgs.byteTwo==127) {
+ I_movieSource=1;
+ midiOut.sendControlChange(1, 77, 0);
+ midiOut.sendControlChange(1, 79, 0);
+ midiOut.sendControlChange(1, 80, 0);
+ }
+ else midiOut.sendControlChange(1, 78, 127);
+ break;
+ case 79:
+ if (eventArgs.byteTwo==127) {
+ I_movieSource=2;
+ midiOut.sendControlChange(1, 77, 0);
+ midiOut.sendControlChange(1, 78, 0);
+ midiOut.sendControlChange(1, 80, 0);
+ }
+ else midiOut.sendControlChange(1, 79, 127);
+ break;
+ case 80:
+ if (eventArgs.byteTwo==127) {
+ I_movieSource=3;
+ midiOut.sendControlChange(1, 77, 0);
+ midiOut.sendControlChange(1, 78, 0);
+ midiOut.sendControlChange(1, 79, 0);
+ }
+ else midiOut.sendControlChange(1, 80, 127);
+ break;
+
+ // probably make controls logarithmic
+ case 81:
+ F_xRotate=(((float) eventArgs.byteTwo)-64)*.1;
+ break;
+ case 82:
+ F_yRotate=(((float) eventArgs.byteTwo)-64)*.1;
+ break;
+ case 83:
+ F_zRotate=(((float) eventArgs.byteTwo)-64)*.1;
+ break;
+ case 84:
+ F_drawStep=(((float) eventArgs.byteTwo)-64)*.1;
+ break;
+ case 85:
+ F_movieSpeed=((float)eventArgs.byteTwo)/64.0;
+ break;
+ case 86:
+ F_drawDecay=((float)eventArgs.byteTwo)/127.0;
+ break;
+ case 87:
+ I_fade2=((float)eventArgs.byteTwo)*2;
+ break;
+ case 88:
+ I_fade1=((float)eventArgs.byteTwo)*2;
+ //printf("fog- %f\n", F_drawDecay);
+ break;
+
+ case 91: //top
+ F_xRotation=90;
+ F_yRotation=90;
+ F_zRotation=0;
+ midiOut.sendControlChange(1, 91, 0);
+ break;
+ case 92: //front
+ F_xRotation=0;
+ F_yRotation=180;
+ F_zRotation=0;
+ midiOut.sendControlChange(1, 92, 0);
+ break;
+
+ //89-92 bottom 4
+
+ }
+ //printf("rotation- %f %f %f\n",F_xRotate,F_yRotate,F_zRotate);
+ //printf(inputMode==PICTURE?"PICTURE mode\n":"GRABBER mode\n");
+ }
+}
+void testApp::setMidiState(){
+ int knobs[32];
+ int buttons[16];
+ int faders[8];
+ for (int i=0;i<32;i++) knobs[i]=0;
+ for (int i=0;i<16;i++) buttons[i]=0;
+ for (int i=0;i<8;i++) faders[i]=0;
+
+ knobs[0] = (F_scale * 5);
+ knobs[1]=(F_lineWidth*10);
+ knobs[2]=(F_drawAxis/(360.0/127))+64;
+
+ knobs[3]=F_particleAmount/(2000.0f/127);
+ knobs[4]=F_particleLife/(3.0f/127);
+ knobs[5]=(F_particleX*10)+64;
+ knobs[6]=(F_particleY*10)+64;
+ knobs[7]=(F_particleZ*10)+64;
+
+
+ //radio button set
+ buttons[0]=(visMode==FFT_AVG?127:0);
+ buttons[1]=(visMode==FFT_RAW?127:0);
+ buttons[2]=(visMode==WAVEFORM?127:0);
+
+ //radio button set
+ buttons[3]=(inputMode==PICTURE?127:0);
+ buttons[4]=(inputMode==GRABBER?127:0);
+ buttons[5]=B_glitch?127:0;
+ buttons[6]=B_fill?127:0;
+ buttons[7]=B_vSync?127:0;
+
+ buttons[12]=I_movieSource==0?127:0;
+ buttons[13]=I_movieSource==1?127:0;
+ buttons[14]=I_movieSource==2?127:0;
+ buttons[15]=I_movieSource==3?127:0;
+
+ faders[0]=(F_xRotate*10)+64;
+ faders[1]=(F_yRotate*10)+64;
+ faders[2]=(F_zRotate*10)+64;
+ faders[3]=(F_drawStep*10)+64;
+ faders[4]=F_movieSpeed*127;
+
+ faders[5]=(F_drawDecay*127);
+
+ faders[6]=I_fade1/2;
+ faders[7]=I_fade1/2;
+
+ for (int i=0;i<32;i++) midiOut.sendControlChange(1, i+1, knobs[i]);
+ for (int i=0;i<16;i++) midiOut.sendControlChange(1, i+65, buttons[i]);
+ for (int i=0;i<8;i++) midiOut.sendControlChange(1, i+81, faders[i]);
+}
+
+/*
+void sendNoteOn(int channel, int id, int value);
+void sendNoteOff(int channel, int id, int value);
+void sendControlChange(int channel, int id, int value);
+*/
+
+
diff --git a/06_performance/src/testApp.h b/06_performance/src/testApp.h
new file mode 100644
index 0000000..cca9e20
--- /dev/null
+++ b/06_performance/src/testApp.h
@@ -0,0 +1,163 @@
+#ifndef _TEST_APP
+#define _TEST_APP
+
+#include "ofMain.h"
+#include "fft.h"
+#include "FFTOctaveAnalyzer.h"
+
+#define BUFFER_SIZE 1024
+#define BUFFER_FRAMES 512
+
+/*
+ok seriously lets make this good
+
+recording - storage for a bunch of fft
+
+average them on the fly? seems likely
+
+*/
+
+#define OF_ADDON_USING_OFXMIDIIN
+
+#include "ofxMidi.h"
+
+#define FFT_AVG 1
+#define FFT_RAW 2
+#define WAVEFORM 3
+
+#define PICTURE 1
+#define GRABBER 2
+
+
+class testApp : public ofBaseApp, public ofxMidiListener{
+
+ public:
+
+ void setup();
+ void update();
+ void draw();
+
+ void keyPressed (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();
+
+ void audioIn(float * input, int bufferSize, int nChannels);
+
+ FFTOctaveAnalyzer lFFTanalyzer;
+ FFTOctaveAnalyzer rFFTanalyzer;
+
+ ofxMidiIn midiIn;
+ ofxMidiOut midiOut;
+ void newMidiMessage(ofxMidiEventArgs& eventArgs);
+
+ void setMidiState();
+
+
+ private:
+
+ float * left;
+ float * right;
+ int bufferCounter;
+ fft myfft;
+
+ float FFTbuffer[2][BUFFER_SIZE][BUFFER_FRAMES];
+
+ int thisFFTbuffer;
+
+ float lmagnitude[BUFFER_SIZE];
+ float lphase[BUFFER_SIZE];
+ float lpower[BUFFER_SIZE];
+ float lfreq[BUFFER_SIZE/2];
+
+ float rmagnitude[BUFFER_SIZE];
+ float rphase[BUFFER_SIZE];
+ float rpower[BUFFER_SIZE];
+ float rfreq[BUFFER_SIZE/2];
+
+ ofSoundStream soundStream;
+
+ ofImage fbImage;
+
+ //ofImage blendImage;
+
+ ofVideoPlayer blendImage;
+
+ ofFbo renderImage;
+ ofShader maskShader;
+
+ bool showFPS;
+ bool fullScreen;
+
+ ofImage testImage;
+
+ //controllable variables
+ float F_scale;
+ float F_drawFrames;
+ float F_drawStep;
+
+ float F_drawDecay;
+ float F_lineWidth;
+ float F_drawAxis;
+
+ float F_xRotation;
+ float F_yRotation;
+ float F_zRotation;
+
+ float F_xRotate;
+ float F_yRotate;
+ float F_zRotate;
+
+ float lastFrameTime;
+
+ bool draworder;
+ bool B_vSync;
+ bool B_fill;
+
+ int visMode;
+ int inputMode;
+
+ int I_fade1;
+ int I_fade2;
+
+ int I_movieSource;
+ int I_moviePlaying;
+
+ bool B_glitch;
+
+
+
+ unsigned char *gammamap;
+ unsigned char *line1;
+ unsigned char *line2;
+ unsigned char *outBuffer;
+
+ float F_particleAmount;
+ float F_particleLife;
+ float F_particleX;
+ float F_particleY;
+ float F_particleZ;
+
+
+
+ float whitePt;
+ float blackPt;
+ float gamma;
+
+ bool field2; //flag that there is a 2nd field waiting to be processed
+ bool use2fields;
+ int frameTime,grabTime; //keep track of field timing
+
+
+ bool deInterlace;
+ ofTexture outTexture;
+
+ float F_movieSpeed;
+
+
+ ofImage blanker;
+};
+
+#endif
+