From 643442a18323f563f75c20f32ef3488f68b74570 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Tue, 20 Dec 2011 14:32:48 +0000 Subject: initial show version --- Makefile | 466 ++++++++++++++++++++++++++ addons.make | 3 + bin/libs/libfmodex.so | Bin 0 -> 1381296 bytes bin/libs/libfmodexp.so | Bin 0 -> 584676 bytes config.make | 34 ++ src/FFTOctaveAnalyzer.cpp | 98 ++++++ src/FFTOctaveAnalyzer.h | 45 +++ src/fft.cpp | 489 +++++++++++++++++++++++++++ src/fft.h | 33 ++ src/main.cpp | 17 + src/src.zip | Bin 0 -> 5669 bytes src/testApp.cpp | 827 ++++++++++++++++++++++++++++++++++++++++++++++ src/testApp.h | 158 +++++++++ stringMachine.cbp | 93 ++++++ stringMachine.layout | 37 +++ stringMachine.workspace | 9 + thoughts | 0 17 files changed, 2309 insertions(+) create mode 100644 Makefile create mode 100755 addons.make create mode 100644 bin/libs/libfmodex.so create mode 100644 bin/libs/libfmodexp.so create mode 100644 config.make create mode 100644 src/FFTOctaveAnalyzer.cpp create mode 100644 src/FFTOctaveAnalyzer.h create mode 100644 src/fft.cpp create mode 100644 src/fft.h create mode 100644 src/main.cpp create mode 100644 src/src.zip create mode 100644 src/testApp.cpp create mode 100644 src/testApp.h create mode 100644 stringMachine.cbp create mode 100644 stringMachine.layout create mode 100644 stringMachine.workspace create mode 100644 thoughts diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2db4a8b --- /dev/null +++ b/Makefile @@ -0,0 +1,466 @@ +# openFrameworks universal 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.make + +ifeq ($(findstring Android,$(MAKECMDGOALS)),Android) + include $(OF_ROOT)/libs/openFrameworksCompiled/project/android/paths.make + ARCH = android + ifeq ($(shell uname),Darwin) + HOST_PLATFORM = darwin-x86 + else + HOST_PLATFORM = linux-x86 + endif +endif + +ifeq ($(ARCH),android) + COMPILER_OPTIMIZATION = $(ANDROID_COMPILER_OPTIMIZATION) + NDK_PLATFORM = android-8 +else + COMPILER_OPTIMIZATION = $(USER_COMPILER_OPTIMIZATION) +endif + + + + +# you shouldn't modify anything below this line + + +SHELL = /bin/sh +ifneq ($(ARCH),android) + CXX = g++ + ARCH = $(shell uname -m) + ifeq ($(ARCH),x86_64) + LIBSPATH=linux64 + else + LIBSPATH=linux + endif +else + ifeq ($(findstring Release_arm7,$(MAKECMDGOALS)),Release_arm7) + LIBSPATH =android/armeabi-v7a + else + LIBSPATH =android/armeabi + endif + #NDK_ROOT = $(shell cat $(OF_ROOT)/libs/openFrameworksCompiled/project/android/ndk_path.make) + #SDK_ROOT = $(shell cat $(OF_ROOT)/libs/openFrameworksCompiled/project/android/sdk_path.make) + TOOLCHAIN=arm-linux-androideabi-4.4.3 + TOOLCHAIN_PATH=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/ + ANDROID_PREFIX=arm-linux-androideabi- + CC=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)gcc + CXX=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)g++ + AR=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)ar + SYSROOT=$(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/ + CFLAGS += -nostdlib --sysroot=$(SYSROOT) -fno-short-enums + CFLAGS += -I"$(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" -I"$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/include/" -I"$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include" + CFLAGS += -DANDROID +endif + +NODEPS = clean +SED_EXCLUDE_FROM_SRC = $(shell echo $(EXCLUDE_FROM_SOURCE) | sed s/\,/\\\\\|/g) +SOURCE_DIRS = $(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" -or -name "*.cc") +OBJFILES = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(patsubst %.cc,%.o,$(SOURCES)))) + +ifneq (,$(USER_SOURCE_DIR)) + USER_SOURCES = $(shell find $(USER_SOURCE_DIR) -name "*.cpp" -or -name "*.c" -or -name "*.cc") + USER_OBJFILES = $(subst $(USER_SOURCE_DIR)/, ,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(patsubst %.cc,%.o,$(USER_SOURCES))))) +endif + +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 +ifeq ($(ARCH),android) + INCLUDES_FLAGS += -I$(OF_ROOT)/libs/glu/include_android +else + INCLUDES_FLAGS += -I$(OF_ROOT)/libs/glu/include + INCLUDES_FLAGS += $(shell pkg-config glew gstreamer-0.10 gstreamer-video-0.10 gstreamer-base-0.10 libudev --cflags) + #check if gtk exists and add it + GTK = $(shell pkg-config gtk+-2.0 --exists; echo $$?) + ifeq ($(GTK),0) + CFLAGS += $(shell pkg-config gtk+-2.0 --cflags) -DOF_USING_GTK + SYSTEMLIBS += $(shell pkg-config gtk+-2.0 --libs) + endif + + #check if mpg123 exists and add it + MPG123 = $(shell pkg-config libmpg123 --exists; echo $$?) + ifeq ($(MPG123),0) + CFLAGS += -DOF_USING_MPG123 + SYSTEMLIBS += -lmpg123 + endif +endif +LIB_STATIC = $(shell ls $(OF_ROOT)/libs/*/lib/$(LIBSPATH)/*.a 2> /dev/null | grep -v openFrameworksCompiled | grep -v Poco) +LIB_SHARED = $(shell ls $(OF_ROOT)/libs/*/lib/$(LIBSPATH)/*.so 2> /dev/null | grep -v openFrameworksCompiled | sed "s/.*\\/lib\([^/]*\)\.so/-l\1/") +LIB_STATIC += $(OF_ROOT)/libs/poco/lib/$(LIBSPATH)/libPocoNet.a ../../../libs/poco/lib/$(LIBSPATH)/libPocoXML.a ../../../libs/poco/lib/$(LIBSPATH)/libPocoUtil.a ../../../libs/poco/lib/$(LIBSPATH)/libPocoFoundation.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) + + + +ifeq ($(ARCH),android) + LDFLAGS = --sysroot=$(SYSROOT) -nostdlib -L"$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/libs/armeabi" + SYSTEMLIBS += -lstdc++ -lsupc++ -lgcc -lz -lGLESv1_CM -llog -ldl -lm -lc +else + LDFLAGS = -Wl,-rpath=./libs + SYSTEMLIBS += $(shell pkg-config jack glew gstreamer-0.10 gstreamer-video-0.10 gstreamer-base-0.10 gstreamer-app-0.10 libudev --libs) + SYSTEMLIBS += -lglut -lGL -lasound -lopenal -lsndfile -lvorbis -lFLAC -logg -lfreeimage +endif + + +ifeq ($(findstring addons.make,$(wildcard *.make)),addons.make) + ifneq ($(ARCH),android) + ADDONS = $(shell cat addons.make | grep -v ofxAndroid) + else + ADDONS = $(shell cat addons.make) + endif + + ifneq ($(strip $(ADDONS)),) + 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)) + EXCLUDE_LIBS_FILTER = $(addprefix %,$(addsuffix .a,$(ADDONS_LIBS_W_ORDER))) + ADDONS_LIBS_STATICS = $(filter-out $(EXCLUDE_LIBS_FILTER), $(shell find $(ADDONS_BIN_LIBS_DIRS) -name *.a)) + 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)) + else + ADDONS_LIBS_STATICS = $(shell find $(ADDONS_BIN_LIBS_DIRS) -name *.a 2> /dev/null) + endif + + 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))))) + endif +endif + + +ifeq ($(findstring Debug,$(MAKECMDGOALS)),Debug) + TARGET_CFLAGS = -g + TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/$(LIBSPATH)/libopenFrameworksDebug.a + TARGET_NAME = Debug +endif + +ifeq ($(findstring Release,$(MAKECMDGOALS)),Release) + TARGET_CFLAGS = $(COMPILER_OPTIMIZATION) + TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/$(LIBSPATH)/libopenFrameworks.a + TARGET_NAME = Release +endif + +ifeq ($(ARCH),android) + ifeq ($(findstring Debug,$(MAKECMDGOALS)),Debug) + TARGET = libs/armeabi/libOFAndroidApp.so + TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/$(ARCH)/libopenFrameworksDebug.a + LDFLAGS += -Wl,--fix-cortex-a8 -shared + USER_LIBS = $(USER_LIBS_ARM) + endif + + ifeq ($(findstring Release,$(MAKECMDGOALS)),Release) + TARGET = libs/armeabi/libOFAndroidApp.so + TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/$(ARCH)/libopenFrameworks.a + LDFLAGS += -Wl,--fix-cortex-a8 -shared + USER_LIBS = $(USER_LIBS_ARM) + endif + + ifeq ($(findstring Release_arm7,$(MAKECMDGOALS)),Release_arm7) + TARGET_NAME = Release_arm7 + TARGET_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mthumb + TARGET = libs/armeabi-v7a/libOFAndroidApp.so + TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/$(ARCH)/libopenFrameworks_arm7.a + USER_LIBS = $(USER_LIBS_ARM7) + endif + + ifeq ($(findstring Release_neon,$(MAKECMDGOALS)),Release_neon) + TARGET_NAME = Release_neon + TARGET_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon + TARGET = libs/armeabi-v7a/libOFAndroidApp_neon.so + TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/$(ARCH)/libopenFrameworks_neon.a + USER_LIBS = $(USER_LIBS_NEON) + endif + + ifeq ($(findstring TestLink,$(MAKECMDGOALS)),TestLink) + TARGET_NAME = Debug + TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/$(ARCH)/libopenFrameworksDebug.a + LDFLAGS += -Wl,--entry=main,--fix-cortex-a8 + BIN_NAME = $(APPNAME) + TARGET = obj/$(BIN_NAME) + USER_LIBS = $(USER_LIBS_ARM) + endif +else + 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 ($(MAKECMDGOALS),) + TARGET_NAME = Release + BIN_NAME = $(APPNAME) + TARGET = bin/$(BIN_NAME) + TARGET_LIBS = $(OF_ROOT)/libs/openFrameworksCompiled/lib/$(LIBSPATH)/libopenFrameworks.a + endif +endif + +ifeq ($(MAKECMDGOALS),clean) + TARGET = bin/$(APPNAME)_debug bin/$(APPNAME) + TARGET_NAME = Release +endif + + +OBJ_OUTPUT = obj/$(ARCH)$(TARGET_NAME)/ +CLEANTARGET = clean$(TARGET_NAME) + +OBJS = $(addprefix $(OBJ_OUTPUT), $(OBJFILES)) +DEPFILES = $(patsubst %.o,%.d,$(OBJS)) + +USER_OBJS = $(addprefix $(OBJ_OUTPUT), $(USER_OBJFILES)) +DEPFILES += $(patsubst %.o,%.d,$(USER_OBJS)) + +ifeq ($(findstring addons.make,$(wildcard *.make)),addons.make) + ADDONS_OBJS = $(addprefix $(OBJ_OUTPUT), $(ADDONS_OBJFILES)) + DEPFILES += $(patsubst %.o,%.d,$(ADDONS_OBJS)) +endif + +.PHONY: Debug Release all after afterDebugAndroid afterReleaseAndroid + +Release: $(TARGET) after + +Debug: $(TARGET) after + +all: + $(MAKE) Release + +DebugAndroid: $(TARGET) + +ReleaseAndroid: $(TARGET) + +Release_arm7Android: $(TARGET) + +Release_neonAndroid: $(TARGET) afterReleaseAndroid + +TestLinkAndroid: $(TARGET) afterDebugAndroid + +AndroidDebug: + $(MAKE) DebugAndroid + $(MAKE) TestLinkAndroid + +AndroidRelease: + $(MAKE) ReleaseAndroid + $(MAKE) Release_arm7Android + $(MAKE) Release_neonAndroid + + +#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) + $(CC) -c $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o$@ -c $< + +$(OBJ_OUTPUT)%.o: %.cc + @echo "compiling object for: " $< + mkdir -p $(@D) + $(CC) -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) + $(CC) $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o $@ -c $< + +$(OBJ_OUTPUT)%.o: $(OF_ROOT)/%.cc + @echo "compiling addon object for" $< + mkdir -p $(@D) + $(CC) $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o $@ -c $< + +$(OBJ_OUTPUT)%.o: $(USER_SOURCE_DIR)/%.c + @echo "compiling object for: " $< + mkdir -p $(@D) + $(CC) $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o$@ -c $< + +$(OBJ_OUTPUT)%.o: $(USER_SOURCE_DIR)/%.cc + @echo "compiling object for: " $< + mkdir -p $(@D) + $(CC) $(TARGET_CFLAGS) $(CFLAGS) $(ADDONSCFLAGS) $(USER_CFLAGS) -MMD -MP -MF$(OBJ_OUTPUT)$*.d -MT$(OBJ_OUTPUT)$*.d -o$@ -c $< + +$(OBJ_OUTPUT)%.o: $(USER_SOURCE_DIR)/%.cpp + @echo "compiling 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) $(USER_OBJS) $(TARGET_LIBS) $(LIB_STATIC) + @echo 'linking $(TARGET)' + mkdir -p $(@D) + $(CXX) -o $@ $(OBJS) $(ADDONS_OBJS) $(USER_OBJS) $(LDFLAGS) $(USER_LDFLAGS) $(TARGET_LIBS) $(ADDONSLIBS) $(USER_LIBS) $(LIB_STATIC) $(LIB_PATHS_FLAGS) $(LIB_SHARED) $(SYSTEMLIBS) + +-include $(DEPFILES) + +.PHONY: clean cleanDebug cleanRelease CleanAndroid +clean: + rm -rf $(OBJ_OUTPUT) + rm -f $(TARGET) + rm -r bin/libs + +$(CLEANTARGET): + rm -rf $(OBJ_OUTPUT) + rm -f $(TARGET) + rm -rf bin/libs + +CleanAndroid: + rm -Rf obj + rm -f libs/armeabi-v7a/libOFAndroidApp.so + rm -f libs/armeabi/libOFAndroidApp.so + rm -f obj/$(APPNAME) + + +afterDebugAndroid:$(TARGET) + @if [ -d libs/armeabi-v7a ]; then rm -r libs/armeabi-v7a; fi + + @cp $(NDK_ROOT)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/gdbserver libs/armeabi + + #create gdb.setup for armeabi + @echo "set solib-search-path $(PWD)/obj/local/armeabi:$(PWD)/libs/armeabi" > libs/armeabi/gdb.setup + @echo "directory $(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" >> libs/armeabi/gdb.setup + @echo "directory $(PWD)/src" >> libs/armeabi/gdb.setup + @echo "directory $(NDK_ROOT)/sources/cxx-stl/system" >> libs/armeabi/gdb.setup + @echo "directory $(PWD)/libs/armeabi" >> libs/armeabi/gdb.setup + @echo "" >> libs/armeabi/gdb.setup + + @if [ ! -d jni ]; then mkdir jni; fi + @echo "APP_ABI := armeabi" > jni/Application.mk + @echo "#LOCAL_MODULE := OFAndroidApp" > jni/Android.mk + +afterReleaseAndroid:$(TARGET) + @if [ -f obj/$(BIN_NAME) ]; then rm obj/$(BIN_NAME); fi + + @cp $(OF_ROOT)/libs/openFrameworksCompiled/project/android/libneondetection.so libs/armeabi-v7a/ + @cp $(NDK_ROOT)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/gdbserver libs/armeabi-v7a + + #create gdb.setup for armeabi-v7a + @echo "set solib-search-path $(PWD)/obj/local/armeabi-v7a:$(PWD)/libs/armeabi-v7a" > libs/armeabi-v7a/gdb.setup + @echo "directory $(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" >> libs/armeabi-v7a/gdb.setup + @echo "directory $(PWD)/src" >> libs/armeabi-v7a/gdb.setup + @echo "directory $(NDK_ROOT)/sources/cxx-stl/system" >> libs/armeabi-v7a/gdb.setup + @echo "directory $(PWD)/libs/armeabi-v7a" >> libs/armeabi-v7a/gdb.setup + @echo "" >> libs/armeabi-v7a/gdb.setup + + @if [ ! -d jni ]; then mkdir jni; fi + @echo "APP_ABI := armeabi armeabi-v7a" > jni/Application.mk + @echo "#LOCAL_MODULE := OFAndroidApp" > jni/Android.mk + +RESNAME=$(shell echo $(APPNAME)Resources | tr '[A-Z]' '[a-z]') + +AndroidInstall: + if [ -d "bin/data" ]; then \ + mkdir -p res/raw; \ + rm res/raw/$(RESNAME).zip; \ + cd bin/data; \ + zip -r ../../res/raw/$(RESNAME).zip *; \ + cd ../..; \ + fi + if [ -f obj/$(BIN_NAME) ]; then rm obj/$(BIN_NAME); fi + #touch AndroidManifest.xml + $(SDK_ROOT)/tools/android update project --target $(NDK_PLATFORM) --path $(PROJECT_PATH) + ant debug + cp bin/OFActivity-debug.apk bin/$(APPNAME).apk + #if [ "$(shell $(SDK_ROOT)/platform-tools/adb get-state)" = "device" ]; then + $(SDK_ROOT)/platform-tools/adb install -r bin/$(APPNAME).apk; + #fi + $(SDK_ROOT)/platform-tools/adb shell am start -a android.intent.action.MAIN -n cc.openframeworks.$(APPNAME)/cc.openframeworks.$(APPNAME).OFActivity + + +after:$(TARGET) + cp -r $(OF_ROOT)/export/$(LIBSPATH)/libs bin/ + @echo + @echo " compiling done" + @echo " to launch the application" + @echo + @echo " cd bin" + @echo " ./$(BIN_NAME)" + @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/addons.make b/addons.make new file mode 100755 index 0000000..cd4c2cc --- /dev/null +++ b/addons.make @@ -0,0 +1,3 @@ +ofxXmlSettings +ofxMidi + diff --git a/bin/libs/libfmodex.so b/bin/libs/libfmodex.so new file mode 100644 index 0000000..ede2f98 Binary files /dev/null and b/bin/libs/libfmodex.so differ diff --git a/bin/libs/libfmodexp.so b/bin/libs/libfmodexp.so new file mode 100644 index 0000000..8badce9 Binary files /dev/null and b/bin/libs/libfmodexp.so differ diff --git a/config.make b/config.make new file mode 100644 index 0000000..1b76a34 --- /dev/null +++ b/config.make @@ -0,0 +1,34 @@ +# 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 = + + +# USER_LDFLAGS allows to pass custom flags to the linker +# for example libraries like: +# USER_LD_FLAGS = libs/libawesomelib.a + +USER_LDFLAGS = + + +# use this to add system libraries for example: +# USER_LIBS = -lpango + +#USER_LIBS = -lportaudio + + +# change this to add different compiler optimizations to your project + +USER_COMPILER_OPTIMIZATION = -march=native -mtune=native -Os + + +EXCLUDE_FROM_SOURCE="bin,.xcodeproj,obj" diff --git a/src/FFTOctaveAnalyzer.cpp b/src/FFTOctaveAnalyzer.cpp new file mode 100644 index 0000000..4c91eeb --- /dev/null +++ b/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/src/FFTOctaveAnalyzer.h b/src/FFTOctaveAnalyzer.h new file mode 100644 index 0000000..8fef773 --- /dev/null +++ b/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/src/fft.cpp b/src/fft.cpp new file mode 100644 index 0000000..ca3217e --- /dev/null +++ b/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 +#include +#include + +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/src/fft.h b/src/fft.h new file mode 100644 index 0000000..bae5b37 --- /dev/null +++ b/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/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..29b0a27 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,17 @@ +#include "ofMain.h" +#include "testApp.h" + +//======================================================================== +int main( ){ + + ofSetupOpenGL(1024,768, OF_FULLSCREEN); // <-------- 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/src/src.zip b/src/src.zip new file mode 100644 index 0000000..9f80003 Binary files /dev/null and b/src/src.zip differ diff --git a/src/testApp.cpp b/src/testApp.cpp new file mode 100644 index 0000000..9aff6c9 --- /dev/null +++ b/src/testApp.cpp @@ -0,0 +1,827 @@ +#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(1); + midiIn.addListener(this); + + midiOut.listPorts(); + midiOut.openPort(1); + + // 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.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; + + I_fade1=0; + I_fade2=0; + + thisFFTbuffer=0; + + lastFrameTime=ofGetElapsedTimef(); + + draworder=true; //forwards; + + visMode=WAVEFORM; + + B_vSync=true; + B_fill=true; + + inputMode=PICTURE; + + camWidth=720; + camHeight=576; + grabber.initGrabber(camWidth,camHeight); + gammamap=new unsigned char[256]; + line1=new unsigned char[camWidth]; + line2=new unsigned char[camWidth]; + outBuffer=new unsigned char[camWidth*camHeight*3]; + + 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); + } + + outTexture.allocate(camWidth,camHeight, GL_RGB); + deInterlace=true; + B_glitch=false; + + blanker.allocate(64,64,OF_IMAGE_COLOR); + // blanker.loadImage("black.png"); + + + + + setMidiState(); +} + + + +//-------------------------------------------------------------- +void testApp::update(){ + if (inputMode==GRABBER) 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=(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;i270) 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; + } +} + +//-------------------------------------------------------------- +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: + break; + case 5: + 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; + + //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/src/testApp.h b/src/testApp.h new file mode 100644 index 0000000..43540c6 --- /dev/null +++ b/src/testApp.h @@ -0,0 +1,158 @@ +#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; + + 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; + + + + ofVideoGrabber grabber; + + unsigned char *gammamap; + unsigned char *line1; + unsigned char *line2; + unsigned char *outBuffer; + + int camWidth,camHeight; + + 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 + diff --git a/stringMachine.cbp b/stringMachine.cbp new file mode 100644 index 0000000..afb10a9 --- /dev/null +++ b/stringMachine.cbp @@ -0,0 +1,93 @@ + + + + + + diff --git a/stringMachine.layout b/stringMachine.layout new file mode 100644 index 0000000..49b0b97 --- /dev/null +++ b/stringMachine.layout @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stringMachine.workspace b/stringMachine.workspace new file mode 100644 index 0000000..1420ee6 --- /dev/null +++ b/stringMachine.workspace @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/thoughts b/thoughts new file mode 100644 index 0000000..e69de29 -- cgit v1.2.3