pax_global_header00006660000000000000000000000064144646624140014525gustar00rootroot0000000000000052 comment=2f47096f41409fb58a0676fc0f4addaa1861382b flext-0-6-3/000077500000000000000000000000001446466241400126535ustar00rootroot00000000000000flext-0-6-3/.gitignore000066400000000000000000000012321446466241400146410ustar00rootroot00000000000000.DS_Store config.txt pd-darwin/ max-darwin/ buildsys/config-*.txt flext.xcodeproj/project.xcworkspace/ flext.xcodeproj/xcuserdata/ # CompiledObject files *.slo *.lo *.o *.obj *.opp # Precompiled Headers *.gch *.pch # Compiled Dynamic libraries *.so *.dylib *.dll *.pd_linux *.pd_darwin # Fortran module files *.mod # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app # autoconf temporary files Makefile Makefile.in autom4te.cache compile config.guess config.log config.status config.sub configure configure*~ depcomp install-sh libtool ltmain.sh missing source/.deps source/Makefile source/Makefile.in aclocal.m4 m4/ *.pc *.log flext-0-6-3/.gitlab-ci.yml000066400000000000000000000012221446466241400153040ustar00rootroot00000000000000variables: GIT_SUBMODULE_STRATEGY: recursive build_linux: stage: build script: - ./bootstrap.sh - ./configure --with-sdkdir=$HOME/pure-data/src --enable-cmem - make artifacts: paths: - tutorial/*/*.pd_linux expire_in: 1h test_linux: stage: test script: - $CI_PROJECT_DIR/tutorial/pd/test.sh $CI_PROJECT_DIR push_github: stage: deploy script: - git remote add github https://$GITHUB_ACCESS_TOKEN@github.com/$GITHUB_USERNAME/$CI_PROJECT_NAME.git || true # we need some extra treatment because the gitlab-runner doesn't check out the full history - git push github HEAD:master --tags flext-0-6-3/Doxyfile000066400000000000000000000235401446466241400143650ustar00rootroot00000000000000# Doxyfile 1.4.3 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = flext PROJECT_NUMBER = 0.5.0 OUTPUT_DIRECTORY = ./doc CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = /Applications/util/ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES DISTRIBUTE_GROUP_DOC = NO SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = NO HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = YES FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = \ source FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.C \ *.CC \ *.C++ \ *.II \ *.I++ \ *.H \ *.HH \ *.H++ \ *.CS \ *.PHP \ *.PHP3 \ *.M \ *.MM RECURSIVE = NO EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = NO INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = YES CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = YES LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = FLEXT_SYS=2 \ FLEXT_SHARED \ __DOXYGEN__ EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 MAX_DOT_GRAPH_HEIGHT = 1024 MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO flext-0-6-3/Makefile.am000066400000000000000000000003421446466241400147060ustar00rootroot00000000000000# # automake template # added by tim blechmann # modified by Thomas Grill # ACLOCAL_AMFLAGS = -I m4 SUBDIRS = source tutorial # EXTRA_DIST = flext.doxy pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = $(SYSTEM)-flext.pc flext-0-6-3/bootstrap.sh000077500000000000000000000006001446466241400152230ustar00rootroot00000000000000#! /bin/sh ( ( ( test -x "$(which libtoolize)" && libtoolize --force ) || ( # MacOS has no libtoolize... use glibtoolize instead test -x "$(which glibtoolize)" && glibtoolize --force ) ) && aclocal && automake --foreign --add-missing && autoconf ) || ( echo Bootstrapping failed false ) flext-0-6-3/build.bat000066400000000000000000000032161446466241400144440ustar00rootroot00000000000000@echo off rem rem flext - C++ layer for Max/MSP and pd (pure data) externals rem rem Copyright (c) 2001-2005 Thomas Grill (gr@grrrr.org) rem For information on usage and redistribution, and for a DISCLAIMER OF ALL rem WARRANTIES, see the file, "license.txt," in this distribution. rem rem more information on http://grrrr.org/ext rem ------------------------------------------------------------------------ rem rem To build flext or flext-based externals simply run this script. rem Running it without arguments will print some help to the console. rem rem ------------------------------------------------------------------------ echo ------------------------------------------------ set flext=%~dp0 rem Arguments: rem %1 - system (pd/max) rem %2 - compiler (msvc/gcc/mingw/cygwin) rem %3 - target (build/clean/install) set platform=win set rtsys=%1 set compiler=%2 set target=%3 rem --- The subbatch knowns which make utility to use --- set subbatch=%flext%\buildsys\build-%compiler%.bat if "%platform%"=="" goto syntax if "%rtsys%"=="" goto syntax if "%compiler%"=="" goto syntax if not exist "%subbatch%" goto syntax call "%subbatch%" %platform% %rtsys% %target% %4 %5 %6 %7 %8 %9 goto end rem ----------------------------------------- :syntax echo . echo SYNTAX: build [system] [compiler] {target} echo system ... pd / max echo compiler ... msvc / gcc / mingw / cygwin echo target ... all (default) / clean / install echo . echo Please make sure that your make program and compiler can be accessed with the echo system path and that all relevant environment variables are properly set. echo . echo For further information read flext/build.txt echo . :end flext-0-6-3/build.sh000077500000000000000000000031711446466241400143130ustar00rootroot00000000000000#! /bin/bash # flext - C++ layer for Max/MSP and pd (pure data) externals # # Copyright (c) 2001-2005 Thomas Grill (gr@grrrr.org) # For information on usage and redistribution, and for a DISCLAIMER OF ALL # WARRANTIES, see the file, "license.txt," in this distribution. # # more information on http://grrrr.org/ext # ------------------------------------------------------------------------ # # To build flext or flext-based externals simply run this script. # Running it without arguments will print some help to the console. # # ------------------------------------------------------------------------ flext=${0%/*}/ if [ "$flext" = "$0"/ ]; then flext=./ ; fi # Arguments: # $1 - system (pd/max) # $2 - compiler (msvc/gcc/mingw/cygwin) # $3 - target (build/clean/install) unamesys=$(uname -s) case $unamesys in Linux) platform=lnx;; Darwin) platform=mac;; CYGWIN*|MINGW*) platform=win;; *) echo Platform $unamesys not supported; exit;; esac rtsys=$1 compiler=$2 target=$3 # --- The subbatch knows which make utility to use --- subbatch=${flext}buildsys/build-${compiler}.sh if [ -n "$platform" -a -n "$rtsys" -a -n "$compiler" -a -f $subbatch ] then sh $subbatch $platform $rtsys $target $4 $5 $6 $7 $8 $9 else echo echo SYNTAX: build.sh [system] [compiler] {target} echo system ..... pd / max echo compiler ... msvc / gcc / mingw / cygwin echo target ..... build \(default\) / clean / install echo echo Please make sure that your make program and compiler can be accessed with the echo system path and that all relevant environment variables are properly set. echo echo For further information read flext/build.txt echo fi flext-0-6-3/build.txt000066400000000000000000000201001446466241400145040ustar00rootroot00000000000000flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001-2023 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ---------------------------------------------------------------------------- This document consists of the following parts: 0) Important stuff at the beginning 1) Using the flext build system 1.1) Building and installing flext 1.2) Building externals 1.3) Tested configurations 2) Using autoconf 3) Other ways to compile flext and flext-based externals ---------------------------------------------------------------------------- 0) Important stuff at the beginning =================================== Please be aware that the build system might have difficulties handling paths with spaces. Under unix you might get along with escaping your\ path or quoting "your path". Under Windows escaping doesn't work at all and quoting might not work either - therefore it's best not to use spaced paths at all. ---------------------------------------------------------------------------- 1) Using the flext build system =============================== flext provides a universal build system which supports - various operating systems Windows (win) Linux (lnx) MacOSX (mac) - various real-time systems Pure Data (pd) Max/MSP (max) - various make programs GNU make (gnumake) - various compilers Microsoft Visual C/C++ 6.0, .NET 2002/2003/2005/2008 (msvc) GNU gcc 2.95 and above (gcc,cygwin,mingw) Useful combinations of the above are under Windows: pd msvc, using nmake pd cygwin, using GNU make pd mingw, using GNU make (from the CMD prompt, not msys!) max msvc, using nmake max cygwin, using GNU make max mingw, using GNU make (from the CMD prompt, not msys!) under Linux or MacOSX: pd gcc, using GNU make under MacOSX: max gcc, using GNU make - Mach-O externals only (Max 4.5 upwards) There are two central scripts in the flext folder which invoke the building process: - build.sh for bash shells (Linux, MacOSX, cygwin) - build.bat for the Windows command prompt A project needs to provide some information in order to be built properly. By default, this resides in a file called package.txt Please note, that the build system is shell-oriented, which means, that you'll have to launch a command prompt (cmd.exe under Windows) and probably also set some environment variables for your development system (e.g. run vcvars32.bat included with Microsoft Visual Studio) By invoking one of the build scripts (e.g. with "bash build.sh" under unix, or just "build" unter Windows) you'll get some lines of help. Operating System, real-time system and compiler need to be provided as arguments. See buildsys/readme.txt for developer-centered information. 1.1) Prerequisites ================== Linux: - A gnu g/g++ compiler should be present on any system. The command "g++ --version" should show version 2.95 at least. Compiler version >= 3.3 is recommended. OSX: - The developer package must be installed which contains all necessary parts. Windows: - Microsoft Visual Studio 6, .NET 2002/2003/2005/2008 Be sure to use the VCVARS32.BAT (or probably SDKVARS.BAT) command on the prompt to set up the environment variables Also be sure NOT to put flext or other externals into a path containing spaces!! or - cygwin with binutils, gcc and make packages Max: - The Max/MSP SDK must be installed. On OSX, the frameworks therein must be copied to /Library/Frameworks 1.2) Building and installing flext ================================== Flext can build itself using the build system. From the flext main directory, run the build script e.g. under Windows build pd msvc or under unix with bash build.sh pd gcc When you run it for the first time, one or more configuration files will be created from templates - you will get a message on the console. You should edit the files to adapt it to your system. Depending on your platform these will have name like buildsys/config-win-pd-msvc.txt or buildsys/config-lnx-pd-gcc.txt or buildsys/config-mac-max-gcc.txt After editing the files you will have to run the build script again to ensure that flext is built. After successfully building everything, you can install flext with (under Windows) build pd msvc install or (under unix) bash build.sh pd gcc install You will probably have to have superuser rights in order to install things into the default location. (try "sudo" or "su -c" prefixes, or log in as root) 1.3) Building externals ======================= The flext build system can be used to compile flext-based externals or also native Pd and Max/MSP externals, provided there is a package.txt file in the project folder. In the shell, change to the project folder. Then, simply run the flext build script, e.g. under Windows ..\flext\build pd msvc Then install your newly built external with ..\flext\build pd msvc install You can clean up the intermediate build folders with ..\flext\build pd msvc clean or under unix with bash ../flext/build.sh pd gcc Then install your external with bash ../flext/build.sh pd gcc install You can clean up the intermediate build folders with bash ../flext/build.sh pd gcc clean 1.4) Tested configurations ========================== Both flext and flext-based externals have been successfully built with the following combination of platform-system-compiler, build type. A missing combination does not necessarily mean that it won't work. win-pd-msvc, single/multi/shared win-pd-mingw, single/multi/shared (from CMD prompt, not MSYS) win-pd-cygwin, single/multi/shared win-max-msvc, single/multi/shared win-max-cygwin, single/multi/shared win-max-mingw, single/multi/shared mac-pd-gcc, single/multi/shared mac-max-gcc, single/multi/shared lnx-pd-gcc, single/multi/shared ---------------------------------------------------------------------------- 2) Using autoconf ================= Thanks to Tim Blechmann, flext can also be built using autoconf. This only works under unix shells (like bash). When starting from a fresh cvs-based copy of flext first run ./bootstrap.sh then you can run ./configure --help to get a page of options. You need to pass the path to the Pd source files or the Max SDK to the ./configure script, e.g. on OS X with something like ./configure --enable-system=pd --with-sysdir=/Applications/Pd-0.40-2/Contents/Resources/src then build flext with make and install it with sudo make install !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MINGW: the specs file for certain gcc versions seems to be wrong and needs to be fixed before building flext - locate the specs file with "gcc --print-file specs" - open this file with your favourite editor - search for the line "*md_startfile_prefix:" - change the next line "/mingw/lib" to "/lib" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ---------------------------------------------------------------------------- 3) Other ways to compile flext and flext-based externals ======================================================== Flext can be compiled straightforward as a static or shared library, in release or debug mode. Some preprocessor symbols must be defined depending on the build mode and the realtime system it is targetted for. for Max/MSP: FLEXT_SYS = 1 for Pd: FLEXT_SYS = 2 for a debug build: FLEXT_DEBUG for a static single-threaded library: nothing needs to be defined for a static multi-threaded library: FLEXT_THREADS for a shared library (always multi-threaded): FLEXT_SHARED - Windows - Microsoft Visual Studio projects (.vcproj files) Please have a look at the projects delivered with flext and flext-based externals. - MacOSX - Apple Xcode projects (.xcodeproj bundles) Please have a look at the projects delivered with flext and flext-based externals. Xcode projects often use some Location definitions (definable in the Xcode Preferences). - Flext - the flext main folder - PD - the Pd installation - Max SDK - the Max SDK (path ending with "c74support") - Max Common - Max common files (normally /Library/Application\ Support/Cycling\ \'74 ) flext-0-6-3/build/000077500000000000000000000000001446466241400137525ustar00rootroot00000000000000flext-0-6-3/build/config-lnx.def000066400000000000000000000000711446466241400164740ustar00rootroot00000000000000# comment out to inhibit SIMD (Altivec/SSE) usage SIMD=1 flext-0-6-3/build/config-mac.def000066400000000000000000000000711446466241400164330ustar00rootroot00000000000000# comment out to inhibit SIMD (Altivec/SSE) usage SIMD=1 flext-0-6-3/build/config-win.def000066400000000000000000000000711446466241400164700ustar00rootroot00000000000000# comment out to inhibit SIMD (Altivec/SSE) usage SIMD=1 flext-0-6-3/build/gnumake-lnx-gcc.inc000066400000000000000000000002451446466241400174260ustar00rootroot00000000000000ifdef SIMD DEFS += -DFLEXT_USE_SIMD endif ifdef SNDOBJ_LIB SRCS+=$(SRCS_SNDOBJ) HDRS+=$(HDRS_SNDOBJ) endif ifdef STK_LIB SRCS+=$(SRCS_STK) HDRS+=$(HDRS_STK) endif flext-0-6-3/build/gnumake-mac-gcc.inc000066400000000000000000000002451446466241400173650ustar00rootroot00000000000000ifdef SIMD DEFS += -DFLEXT_USE_SIMD endif ifdef SNDOBJ_LIB SRCS+=$(SRCS_SNDOBJ) HDRS+=$(HDRS_SNDOBJ) endif ifdef STK_LIB SRCS+=$(SRCS_STK) HDRS+=$(HDRS_STK) endif flext-0-6-3/build/gnumake-win-cygwin.inc000066400000000000000000000003371446466241400201700ustar00rootroot00000000000000ifdef SIMD DEFS += -DFLEXT_USE_SIMD endif ifdef SNDOBJ SRCS+=$(SRCS_SNDOBJ) HDRS+=$(HDRS_SNDOBJ) INCPATH+=-I$(SNDOBJ) LIBS+=-lsndobj endif ifdef STK SRCS+=$(SRCS_STK) HDRS+=$(HDRS_STK) INCPATH+=-I$(STK) LIBS+=-lstk endif flext-0-6-3/build/gnumake-win-gcc.inc000066400000000000000000000003521446466241400174210ustar00rootroot00000000000000ifdef SIMD DEFS += -DFLEXT_USE_SIMD endif ifdef ATOMICOPSPATH DEFS += -DUSE_ATOMIC_OPS endif ifdef SNDOBJ_LIB SRCS+=$(SRCS_SNDOBJ) HDRS+=$(HDRS_SNDOBJ) endif ifdef STK_LIB SRCS+=$(SRCS_STK) HDRS+=$(HDRS_STK) endif flext-0-6-3/build/gnumake-win-mingw.inc000066400000000000000000000003371446466241400200110ustar00rootroot00000000000000ifdef SIMD DEFS += -DFLEXT_USE_SIMD endif ifdef SNDOBJ SRCS+=$(SRCS_SNDOBJ) HDRS+=$(HDRS_SNDOBJ) INCPATH+=-I$(SNDOBJ) LIBS+=-lsndobj endif ifdef STK SRCS+=$(SRCS_STK) HDRS+=$(HDRS_STK) INCPATH+=-I$(STK) LIBS+=-lstk endif flext-0-6-3/build/nmake-win-msvc.inc000066400000000000000000000003141446466241400172770ustar00rootroot00000000000000!ifdef SIMD DEFS=$(DEFS) /DFLEXT_USE_SIMD !endif !ifdef SNDOBJ_LIB SRCS=$(SRCS) $(SRCS_SNDOBJ) HDRS=$(HDRS) $(HDRS_SNDOBJ) !endif !ifdef STK_LIB SRCS=$(SRCS) $(SRCS_STK) HDRS=$(HDRS) $(HDRS_STK) !endif flext-0-6-3/buildsys/000077500000000000000000000000001446466241400145115ustar00rootroot00000000000000flext-0-6-3/buildsys/build-cygwin.sh000077500000000000000000000002071446466241400174440ustar00rootroot00000000000000#! /bin/bash build=${0%/*}/ make -f ${build}gnumake.mak PLATFORM=$1 RTSYS=$2 COMPILER=cygwin BUILDPATH=${build} $3 $4 $5 $6 $7 $8 $9 flext-0-6-3/buildsys/build-gcc.sh000077500000000000000000000004171446466241400167030ustar00rootroot00000000000000#! /bin/bash build=${0%/*}/ if [ $(which make) ]; then MAKE=make elif [ $(which mingw32-make) ]; then MAKE=mingw32-make else echo make utility not found exit fi $MAKE -f ${build}gnumake.mak PLATFORM=$1 RTSYS=$2 COMPILER=gcc BUILDPATH=${build} $3 $4 $5 $6 $7 $8 $9 flext-0-6-3/buildsys/build-mingw.bat000066400000000000000000000002001446466241400174070ustar00rootroot00000000000000@set build=%~dp0 mingw32-make -f %build%gnumake.mak PLATFORM=%1 RTSYS=%2 COMPILER=mingw BUILDPATH=%build% %3 %4 %5 %6 %7 %8 %9 flext-0-6-3/buildsys/build-msvc.bat000066400000000000000000000003321446466241400172440ustar00rootroot00000000000000@set build=%~dp0 @rem workaround for MSVC 2005 command prompt, where LIBPATH is predefined @set LIBPATH= @echo on nmake -f "%build%nmake.mak" PLATFORM=%1 RTSYS=%2 COMPILER=msvc BUILDPATH=%build% %3 %4 %5 %6 %7 %8 %9 flext-0-6-3/buildsys/gnumake-ext.inc000066400000000000000000000000201446466241400174210ustar00rootroot00000000000000OUTNAME=$(NAME) flext-0-6-3/buildsys/gnumake-flext.inc000066400000000000000000000000571446466241400177550ustar00rootroot00000000000000DEFS+=-DFLEXT_EXPORTS OUTNAME=lib$(FLEXTNAME) flext-0-6-3/buildsys/gnumake-sub.mak000066400000000000000000000016521446466241400174250ustar00rootroot00000000000000# include flext version number include $(BUILDPATH)version.inc # system settings include $(BUILDPATH)config-$(PLATFORM)-$(RTSYS)-$(COMPILER).txt ############################### # project specific definitions # package info ifneq ($(PKGINFO),) include $(PKGINFO) endif # special settings ifdef USRCONFIG include $(USRCONFIG) endif # package specific make stuff ifdef USRMAKE include $(USRMAKE) endif ############################## # flext-specific definitions include $(BUILDPATH)gnumake.inc include $(BUILDPATH)gnumake-$(BUILDCLASS).inc ############################## # platform-specific make stuff include $(BUILDPATH)$(PLATFORM)/$(RTSYS)/gnumake-$(COMPILER).inc include $(BUILDPATH)$(PLATFORM)/$(RTSYS)/gnumake-$(COMPILER)-$(BUILDCLASS).inc ############################## # general make stuff include $(BUILDPATH)$(PLATFORM)/gnumake-$(COMPILER).inc include $(BUILDPATH)$(PLATFORM)/gnumake-$(COMPILER)-$(BUILDCLASS).inc flext-0-6-3/buildsys/gnumake.inc000066400000000000000000000027301446466241400166350ustar00rootroot00000000000000############################################## # cross-compilation ############################################## #ifndef ARCH #ifeq ("$(shell uname -p)","powerpc") #ARCH := ppc #else #ARCH := $(shell uname -p) #endif #endif ############################################## # some compiler definitions ############################################## CFLAGS += $(UFLAGS) $(foreach arch,$(ARCH),$(eval CFLAGS_$(arch) += $$(UFLAGS_$(arch)) ) ) ifdef DEBUG DEFS += -D_DEBUG CFLAGS += $(DFLAGS) define ARCH_FLAGS CFLAGS_$(1) += $$(DFLAGS_$(1)) endef else ## profile and release DEFS += -DNDEBUG CFLAGS += $(OFLAGS) define ARCH_FLAGS CFLAGS_$(1) += $$(OFLAGS_$(1)) endef endif $(foreach arch,$(ARCH),$(eval $(call ARCH_FLAGS,$(arch)))) ifdef SHARED # --- shared --- DEFS += -DFLEXT_SHARED else ifdef THREADED # --- static multi-threaded --- DEFS += -DFLEXT_THREADS else # --- static single-threaded --- endif endif ############################################## # name of flext library ############################################## ifdef SHARED TYPEEXT := _ else ifdef THREADED TYPEEXT := _t else TYPEEXT := _s endif endif ifdef DEBUG MODEEXT := d else ifdef PROFILE MODEEXT := p else MODEEXT := ifdef SHARED TYPEEXT := endif endif endif FLEXTNAME := flext-$(RTSYS)$(TYPEEXT)$(MODEEXT) ############################################## # product name and folder ############################################## ifndef SRCDIR SRCDIR := . endif OUTSUB := $(TARGETMODE)-$(TARGETTYPE) flext-0-6-3/buildsys/gnumake.mak000066400000000000000000000062721446466241400166410ustar00rootroot00000000000000# required settings: # # PLATFORM - win/mac/lnx # RTSYS - pd/max # COMPILER - msvc/gcc/mingw/cygwin # BUILDPATH including trailing / ############################################### # package info ifndef PKGINFO PKGINFO=package.txt endif ifneq ($(PKGINFO),) include $(PKGINFO) endif ifndef NAME $(error "NAME variable must be defined (name of target)") endif ifndef SRCS $(error "SRCS variable must be defined (list of source files)") endif ############################################### # check variables ifndef BUILDCLASS BUILDCLASS := ext endif ifndef BUILDMODE BUILDMODE := release endif ifndef BUILDTYPE BUILDTYPE := single endif ############################## #ifndef TARGETMODE #TARGETMODE := $(BUILDMODE) #endif #ifndef TARGETTYPE #TARGETTYPE := $(BUILDTYPE) #endif ############################################### ifeq ($(PLATFORM),win) # substitute eventual \ by / UBUILDPATH := $(subst \,/,$(BUILDPATH)) else UBUILDPATH := $(BUILDPATH) endif ############################################### SYSCONFIG := $(UBUILDPATH)config-$(PLATFORM)-$(RTSYS)-$(COMPILER).txt SYSDEFAULT := $(UBUILDPATH)$(PLATFORM)/$(RTSYS)/config-$(COMPILER).def MAKE_OPTIONS := -f $(UBUILDPATH)gnumake-sub.mak \ $(MFLAGS) PLATFORM=$(PLATFORM) RTSYS=$(RTSYS) COMPILER=$(COMPILER) \ BUILDPATH=$(UBUILDPATH) PKGINFO=$(PKGINFO) BUILDCLASS=$(BUILDCLASS) ############################################### ifdef BUILDDIR USRCONFIG := config.txt USRDEFAULT := $(BUILDDIR)/config-$(PLATFORM).def USRMAKE := $(BUILDDIR)/gnumake-$(PLATFORM)-$(COMPILER).inc MAKE_OPTIONS += USRCONFIG=$(USRCONFIG) USRMAKE=$(USRMAKE) endif ############################################### # include file describing default target dependencies .PHONY : all build clean install profile include $(BUILDPATH)targets.inc include $(BUILDPATH)targets-$(BUILDCLASS).inc ############################################### .PRECIOUS: $(SYSCONFIG) $(USRCONFIG) $(SYSCONFIG): $(SYSDEFAULT) ifeq ($(COMPILER),mingw) @copy $(subst /,\,$<) $(subst /,\,$@) else @cp $< $@ endif @echo ------------------------------------------------------------------------- @echo A default system configuration file has been created. @echo Please edit $(SYSCONFIG) @echo to match your platform, then start again. @echo ------------------------------------------------------------------------- ifeq ($(COMPILER),mingw) @exit 1 else @false endif ifdef BUILDDIR $(USRCONFIG): $(USRDEFAULT) ifeq ($(COMPILER),mingw) @copy $(subst /,\,$<) $(subst /,\,$@) else @cp $< $@ endif @echo ------------------------------------------------------------------------- @echo A default package configuration file has been created. @echo Please edit $(USRCONFIG), then start again. @echo ------------------------------------------------------------------------- ifeq ($(COMPILER),mingw) @exit 1 else @false endif $(USRDEFAULT) $(USRMAKE): @echo ------------------------------------------------------------------------- @echo Your combination of platform, system and compiler is not supported yet. @echo Required files: @echo $(USRDEFAULT) @echo and @echo $(USRMAKE) @echo ------------------------------------------------------------------------- ifeq ($(COMPILER),mingw) @exit 1 else @false endif endif flext-0-6-3/buildsys/lnx/000077500000000000000000000000001446466241400153125ustar00rootroot00000000000000flext-0-6-3/buildsys/lnx/gnumake-gcc-ext.inc000066400000000000000000000020511446466241400207620ustar00rootroot00000000000000# build class specific settings TARGET=$(TARGETPATH)/$(TARGETNAME) INSTTARGET=$(TARGET) INCPATH += -I$(FLEXTINC) LIBPATH += -L$(FLEXTLIB) #ifdef SHARED #LIBS += -l$(FLEXTNAME).$(FLEXTMAJOR).$(FLEXTMINOR) #else LIBS += -l$(FLEXTNAME) #endif ############################################## # default target _build_: $(TARGET) $(CSRCS) $(CPPSRCS): $(patsubst %,$(SRCDIR)/%,$(HDRS)) touch $@ $(TARGETPATH): mkdir -p $@ $(TARGETPATH)/%.opp : $(SRCDIR)/%.cpp -mkdir -p $(dir $@) $(CXX) -c $(CXXFLAGS) $(CFLAGS) $(DEFS) $(INCPATH) $< -o $@ $(TARGETPATH)/%.o : $(SRCDIR)/%.c -mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(DEFS) $(INCPATH) $< -o $@ $(TARGET):: $(TARGETPATH) $(TARGET):: $(COBJS) $(CPPOBJS) $(CXX) $(LDFLAGS) $(LIBPATH) -o $@ $(COBJS) $(CPPOBJS) $(LIBS) chmod 755 $@ ifndef DEBUG ifndef PROFILE strip --strip-unneeded $@ endif endif ############################################## _clean_: -rm -rf $(TARGETPATH) ############################################## $(INSTPATH): -mkdir -p $@ _install_: $(INSTPATH) install $(TARGET) $(INSTPATH) flext-0-6-3/buildsys/lnx/gnumake-gcc-flext.inc000066400000000000000000000034601446466241400213110ustar00rootroot00000000000000# build class specific settings CMPNAME=$(OUTNAME).$(EXT).$(FLEXTMAJOR).$(FLEXTMINOR) VERNAME=$(CMPNAME).$(FLEXTMICRO) TARGET=$(TARGETPATH)/$(VERNAME) INSTTARGET=$(TARGET) ifdef SHARED LDFLAGS += -Wl,-soname,$(CMPNAME) endif ############################################## # default target _build_: $(TARGET) $(CSRCS) $(CPPSRCS): $(patsubst %,$(SRCDIR)/%,$(HDRS)) touch $@ $(TARGETPATH): -mkdir -p $@ $(TARGETPATH)/%.opp : $(SRCDIR)/%.cpp -mkdir -p $(dir $@) $(CXX) -c $(CXXFLAGS) $(CFLAGS) $(DEFS) $(INCPATH) $< -o $@ $(TARGETPATH)/%.o : $(SRCDIR)/%.c -mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(DEFS) $(INCPATH) $< -o $@ $(TARGET) :: $(TARGETPATH) $(TARGET) :: $(COBJS) $(CPPOBJS) ifdef SHARED $(CXX) $(LDFLAGS) $(LIBPATH) -o $@ $(COBJS) $(CPPOBJS) $(LIBS) chmod 755 $@ ifndef DEBUG ifndef PROFILE strip --strip-unneeded $@ endif endif else $(AR) rc $@ $(COBJS) $(CPPOBJS) endif ############################################## _clean_: -rm -rf $(TARGETPATH) ############################################## $(FLEXTINC) $(FLEXTLIB) $(FLEXTSYS) $(FLEXTBIN): -mkdir -p $@ _install_: $(FLEXTINC) $(FLEXTLIB) $(FLEXTSYS) $(FLEXTBIN) install $(TARGET) $(FLEXTLIB) ifdef SHARED /sbin/ldconfig -l $(FLEXTLIB)/$(VERNAME) -ln -sf $(CMPNAME) $(FLEXTLIB)/$(OUTNAME).$(EXT) else -ln -sf $(VERNAME) $(FLEXTLIB)/$(TARGETNAME) endif # make directories for f in $(dir $(patsubst %,$(FLEXTINC)/%,$(HDRS) $(SRCS))); do mkdir -p $$f; done # install headers (each one separately as relative paths might occur) for f in $(HDRS) $(SRCS); do install $(SRCDIR)/$$f $(FLEXTINC)/$$f; done # transfer build system # cp -rf buildsys $(FLEXTSYS) # install build.sh $(FLEXTSYS) # chmod -R a+rx $(FLEXTSYS) # make convenience script # echo bash $(FLEXTSYS)/build.sh $$\* > $(FLEXTBIN)/flext-build.sh # chmod a+rx $(FLEXTBIN)/flext-build.sh flext-0-6-3/buildsys/lnx/gnumake-gcc.inc000066400000000000000000000030201446466241400201610ustar00rootroot00000000000000############################################## CFLAGS += -I/usr/include/pd LDFLAGS += -L/usr/lib ############################################## ifndef FLEXTINC FLEXTINC=$(FLEXTPREFIX)/include/flext endif ifndef FLEXTLIB FLEXTLIB=$(FLEXTPREFIX)/lib endif ifndef FLEXTSYS FLEXTSYS=$(FLEXTPREFIX)/lib/flext endif ifndef FLEXTBIN FLEXTBIN=$(FLEXTPREFIX)/bin endif ############################################## OBJPATH=$(OUTPATH)/$(OUTSUB) TARGETPATH=$(OBJPATH) TARGETNAME=$(OUTNAME).$(EXT) ############################################## CFLAGS += -pthread -fPIC -fvisibility-inlines-hidden LDFLAGS += -pthread -shared ############################################## ifdef DEBUG CFLAGS += -g LDFLAGS += -g else ifdef PROFILE CFLAGS += -g -pg LDFLAGS += -g -pg else LDFLAGS += -Wl,-S endif endif ############################################## ifdef STK_INC INCPATH += -I$(STK_INC) endif ifdef STK_LIB LIBS += $(STK_LIB) endif ############################################## ifdef SNDOBJ_INC INCPATH += -I$(SNDOBJ_INC) endif ifdef SNDOBJ_LIB LIBS += $(SNDOBJ_LIB) endif ############################################## ifdef LOCKFREE INCPATH += -I$(LOCKFREE) endif ifdef ATOMIC_OPS INCPATH += -I$(ATOMIC_OPS)/src DEFS += -DUSE_ATOMIC_OPS endif ############################################## CSRCS=$(patsubst %.c,$(SRCDIR)/%.c,$(filter %.c,$(SRCS))) CPPSRCS=$(patsubst %.cpp,$(SRCDIR)/%.cpp,$(filter %.cpp,$(SRCS))) COBJS=$(patsubst %.c,$(OBJPATH)/%.o,$(filter %.c,$(SRCS))) CPPOBJS=$(patsubst %.cpp,$(OBJPATH)/%.opp,$(filter %.cpp,$(SRCS))) flext-0-6-3/buildsys/lnx/pd/000077500000000000000000000000001446466241400157155ustar00rootroot00000000000000flext-0-6-3/buildsys/lnx/pd/config-gcc.def000066400000000000000000000033221446466241400203740ustar00rootroot00000000000000# where is the PD source package? # (this should point to the main folder, which has a "src" (PD Vanilla) or "include" (PD extended) subfolder) PDPATH=/usr/local/src/pd ############################################################### # prefix for flext installation # headers are in $(FLEXTPREFIX)/include/flext # libraries are in $(FLEXTPREFIX)/lib # build system is in $(FLEXTPREFIX)/lib/flext FLEXTPREFIX=/usr/local ############################################################### # where should the external be built? OUTPATH=pd-linux # where should the external be installed? INSTPATH=/usr/local/lib/pd/extra ############################################################### # STK (synthesis tool kit) support # http://ccrma.stanford.edu/software/stk # where to find the STK header files (e.g. stk.h) STK_INC=/usr/local/include/stk # where to find the STK library (normally libstk.a) # (comment out STK_LIB if you don't use STK) #STK_LIB=/usr/local/lib/libstk.a ############################################################### # SndObj support # http://music.nuim.ie//musictec/SndObj # where to find the SndObj header files (e.g. sndobj.h) SNDOBJ_INC=/usr/local/include/sndobj # where to find the SndObj library (normally libsndobj.a) # (comment out STK_LIB if you don't use SndObj) #SNDOBJ_LIB=/usr/local/lib/libsndobj.a ############################################################### # make flags (e.g. use multiprocessor) #MFLAGS=-j 2 # user defined compiler flags # (check if they match your system!) UFLAGS=-ffast-math # don't overload new and delete operators UFLAGS+=-DFLEXT_USE_CMEM # user defined optimization flags # (check if they match your system!) OFLAGS=-O3 # optimizations for build system OFLAGS+=-mtune=native flext-0-6-3/buildsys/lnx/pd/gnumake-gcc-ext.inc000066400000000000000000000000151446466241400213630ustar00rootroot00000000000000EXT=pd_linux flext-0-6-3/buildsys/lnx/pd/gnumake-gcc-flext.inc000066400000000000000000000000461446466241400217110ustar00rootroot00000000000000ifdef SHARED EXT=so else EXT=a endif flext-0-6-3/buildsys/lnx/pd/gnumake-gcc.inc000066400000000000000000000001751446466241400205740ustar00rootroot00000000000000DEFS += -DFLEXT_SYS=2 -DPD INCPATH += -I$(PDPATH)/src -I$(PDPATH)/include -I$(PDPATH)/include/pd LIBPATH += -L$(PDPATH)/bin flext-0-6-3/buildsys/mac/000077500000000000000000000000001446466241400152515ustar00rootroot00000000000000flext-0-6-3/buildsys/mac/gnumake-gcc-ext.inc000066400000000000000000000013751446466241400207310ustar00rootroot00000000000000# build class specific settings LDFLAGS += -framework ApplicationServices INCPATH += -I$(FLEXTINC) LIBPATH += -L$(FLEXTLIB) LIBS += -l$(FLEXTNAME) # common compilation stuff include $(BUILDPATH)$(PLATFORM)/gnumake-gcc-targets.inc ##### linking ################### $(TARGET) :: $(OBJPATH) $(TARGETPATH) $(TARGET) :: $(PRECOMDST) $(COBJS) $(CPPOBJS) $(CXX) $(LDFLAGS) $(LIBPATH) -o $@ $(COBJS) $(CPPOBJS) $(LIBS) ifdef DEBUG else ifdef PROFILE else strip -x $@ endif endif chmod 755 $@ ifdef TARGETPOST $(TARGET) :: $(TARGETPOST) endif ################################### # Attention: $@ doesn't work for paths with spaces.... $(INSTPATH): -mkdir -p $(INSTPATH) _install_:: $(INSTPATH) # copy plain file or whole bundle cp -R $(INSTTARGET) $(INSTPATH) flext-0-6-3/buildsys/mac/gnumake-gcc-flext.inc000066400000000000000000000044611446466241400212520ustar00rootroot00000000000000# build class specific settings ifdef SHARED LDFLAGS += -install_name $(FLEXTLIB)/$(TARGETNAME) LDFLAGS += -current_version $(FLEXTMAJOR).$(FLEXTMINOR).$(FLEXTMICRO) LDFLAGS += -compatibility_version $(FLEXTMAJOR).$(FLEXTMINOR) LDFLAGS += -preload -seg1addr 0xd0000000 endif # common compilation stuff include $(BUILDPATH)$(PLATFORM)/gnumake-gcc-targets.inc ##### linking ################### $(TARGET) :: $(OBJPATH) $(TARGETPATH) $(TARGET) :: $(PRECOMDST) $(COBJS) $(CPPOBJS) ifdef SHARED $(CXX) $(LDFLAGS) $(LIBPATH) -o $@ $(COBJS) $(CPPOBJS) $(LIBS) ifdef DEBUG else ifdef PROFILE else ifndef STRIP STRIP=strip endif $(STRIP) -x $@ || true endif endif chmod 755 $@ else libtool -static -o $@ $(COBJS) $(CPPOBJS) endif ifdef TARGETPOST $(TARGET) :: $(TARGETPOST) endif ################################### $(FLEXTINC): -mkdir -p $@ $(FLEXTLIB): -mkdir -p $@ _install_: $(FLEXTINC) $(FLEXTLIB) ifdef FLEXTFRAMEWORK # --- install as framework --- mkdir -p $(FLEXTFRAMEWORK)/Versions/$(FLEXTMAJOR).$(FLEXTMINOR)/Headers ln -sfh ./$(FLEXTMAJOR).$(FLEXTMINOR) $(FLEXTFRAMEWORK)/Versions/Current ln -sfh ./Versions/Current/Headers $(FLEXTFRAMEWORK)/Headers install $(TARGET) $(FLEXTFRAMEWORK)/Versions/Current ifdef SHARED # make link without lib... and extension ln -sf ./Versions/Current/$(VERNAME) $(FLEXTFRAMEWORK)/$(patsubst lib%,%,$(basename $(TARGETNAME))) else ranlib $(FRAMEWORK)/Versions/Current/$(VERNAME) ln -sf ./Versions/Current/$(VERNAME) $(FLEXTFRAMEWORK)/$(TARGETNAME) endif install $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(FLEXTFRAMEWORK)/Headers else # --- install as dynamic library --- install $(TARGET) $(FLEXTLIB) ifndef SHARED # have to rerun ranlib at install dir ?! # ifndef RANLIB # RANLIB=ranlib # endif # ranlib $(FLEXTLIB)/$(VERNAME) endif ifdef VERNAME ln -sf $(VERNAME) $(FLEXTLIB)/$(TARGETNAME) endif # make directories for f in $(dir $(patsubst %,$(FLEXTINC)/%,$(HDRS) $(SRCS))); do mkdir -p $$f; done # install headers (each one separately as relative paths might occur) for f in $(HDRS) $(SRCS); do install $(SRCDIR)/$$f $(FLEXTINC)/$$f; done endif # transfer build system # cp -rf buildsys $(FLEXTSYS) # install build.sh $(FLEXTSYS) # chmod -R a+rx $(FLEXTSYS) # make convenience script # echo bash $(FLEXTSYS)/build.sh $$\* > $(FLEXTBIN)/flext-build.sh # chmod a+rx $(FLEXTBIN)/flext-build.sh flext-0-6-3/buildsys/mac/gnumake-gcc-targets.inc000066400000000000000000000044541446466241400216030ustar00rootroot00000000000000############################################## CSRCS := $(patsubst %.c,$(SRCDIR)/%.c,$(filter %.c,$(SRCS))) CPPSRCS := $(patsubst %.cpp,$(SRCDIR)/%.cpp,$(filter %.cpp,$(SRCS))) COBJS := $(patsubst %.c,$(OBJPATH)/%.o,$(filter %.c,$(SRCS))) CPPOBJS := $(patsubst %.cpp,$(OBJPATH)/%.opp,$(filter %.cpp,$(SRCS))) ############################################## # default target _build_: $(TARGET) $(CSRCS) $(CPPSRCS): $(patsubst %,$(SRCDIR)/%,$(HDRS)) touch $@ # Attention: $@ doesn't work for paths with spaces.... $(OBJPATH): -mkdir -p $(OBJPATH) # Attention: $@ doesn't work for paths with spaces.... $(TARGETPATH): -mkdir -p $(TARGETPATH) ##### precompiled header file ################### ifdef PRECOMPILE PRECOMSRC := $(SRCDIR)/$(PRECOMPILE) else PRECOMSRC := $(FLEXTINC)/flext.h endif ifdef PRECOMSRC PRECOMDST := $(OBJPATH)/$(notdir $(PRECOMSRC)).gch PRECOMINC := -I $(OBJPATH) endif $(PRECOMDST) : $(PRECOMSRC) $(patsubst %,$(SRCDIR)/%,$(HDRS)) -mkdir -p $(dir $@) $(CXX) -c $(CFLAGS) $(DEFS) $(INCPATH) $(PRECOMSRC) -o $@ ifndef ARCH ##### non-architecture-specific compilation ################### $(OBJPATH)/%.opp : $(SRCDIR)/%.cpp -mkdir -p $(dir $@) $(CXX) -c $(CFLAGS) $(CXXFLAGS) $(DEFS) $(PRECOMINC) $(INCPATH) $^ -o $@ $(OBJPATH)/%.o : $(SRCDIR)/%.c -mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(DEFS) $(PRECOMINC) $(INCPATH) $^ -o $@ else # ARCH ##### architecture-specific compilation ################### define ARCH_COMPILE $(OBJPATH)/%.opp_$(1) : $(SRCDIR)/%.cpp -mkdir -p $(dir $$@) $(CXX) -c $(CFLAGS) $(CXXFLAGS) -arch $(1) $$(CFLAGS_$(1)) $(DEFS) $(PRECOMINC) $(INCPATH) $$^ -o $$@ $(OBJPATH)/%.o_$(1) : $(SRCDIR)/%.c -mkdir -p $(dir $$@) $(CC) -c $(CFLAGS) -arch $(1) $$(CFLAGS_$(1)) $(DEFS) $(PRECOMINC) $(INCPATH) $$^ -o $$@ endef ##### make fat object file ################### $(OBJPATH)/%.opp : $(foreach arch,$(ARCH),$(OBJPATH)/%.opp_$(arch)) lipo $^ -create -output $@ $(OBJPATH)/%.o : $(foreach arch,$(ARCH),$(OBJPATH)/%.o_$(arch)) lipo $^ -create -output $@ endif # ARCH # implement for all archs in ARCH # for some strange reason this must be OUTSIDE an ifdef/endif clause $(foreach arch,$(ARCH),$(eval $(call ARCH_COMPILE,$(arch)))) ############################################## _clean_: -rm -rf $(TARGETPATH) -rm -rf $(OBJPATH) ############################################## flext-0-6-3/buildsys/mac/gnumake-gcc.inc000066400000000000000000000027201446466241400201260ustar00rootroot00000000000000############################################## ifneq (,$(findstring Frameworks,$(FLEXTPREFIX))) FLEXTFRAMEWORK := $(FLEXTPREFIX)/flext.framework endif ifdef FLEXTFRAMEWORK ifndef FLEXTLIB FLEXTLIB := $(FLEXTFRAMEWORK) endif ifndef FLEXTINC FLEXTINC := $(FLEXTFRAMEWORK)/Headers endif ifndef FLEXTSYS FLEXTSYS := $(FLEXTFRAMEWORK)/Resources endif else ifndef FLEXTLIB FLEXTLIB := $(FLEXTPREFIX)/lib endif ifndef FLEXTINC FLEXTINC := $(FLEXTPREFIX)/include/flext endif ifndef FLEXTSYS FLEXTSYS := $(FLEXTPREFIX)/lib/flext endif endif FLEXTBIN := $(FLEXTPREFIX)/bin ############################################## CXXFLAGS += -fvisibility-inlines-hidden LDFLAGS += -dynamic -framework Accelerate ############################################## ifdef DEBUG CFLAGS += -g LDFLAGS += -g else ifdef PROFILE CFLAGS += -g LDFLAGS += -g else LDFLAGS += -Wl,-S endif endif ############################################## ifdef STK_INC INCPATH += -I$(STK_INC) endif ifdef STK_LIB LIBS += $(STK_LIB) endif ############################################## ifdef SNDOBJ_INC INCPATH += -I$(SNDOBJ_INC) endif ifdef SNDOBJ_LIB LIBS += $(SNDOBJ_LIB) endif ############################################## ifdef LOCKFREE INCPATH += -I$(LOCKFREE) endif ifdef ATOMIC_OPS INCPATH += -I$(ATOMIC_OPS)/src DEFS += -DUSE_ATOMIC_OPS endif ############################################## LDFLAGS += $(patsubst %,-arch %,$(ARCH)) ifdef OSXSDK CFLAGS += -isysroot $(OSXSDK) LDFLAGS += -isysroot $(OSXSDK) endif flext-0-6-3/buildsys/mac/max/000077500000000000000000000000001446466241400160365ustar00rootroot00000000000000flext-0-6-3/buildsys/mac/max/config-gcc.def000066400000000000000000000043341446466241400205210ustar00rootroot00000000000000# where are the Max/MSP SDK header files? MAXSDKPATH=/Applications/MaxMSP\ 4.6/MaxMSP-SDK/c74support ############################################################### # prefix for flext installation # headers are in $(FLEXTPREFIX)/include/flext # libraries are in $(FLEXTPREFIX)/lib # build system is in $(FLEXTPREFIX)/lib/flext FLEXTPREFIX=/usr/local ############################################################### # where should the external be built? OUTPATH=max-darwin # where should the external be installed? INSTPATH=/Applications/MaxMSP\ 4.6/Cycling\ \'74/externals/flext # where should the initialization files be installed? INITPATH=/Applications/MaxMSP\ 4.6/Cycling\ \'74/init # where should the help files be installed? HELPPATH=/Applications/MaxMSP\ 4.6/max-help/flext ############################################################### # STK (synthesis tool kit) support # http://ccrma.stanford.edu/software/stk # where to find the STK header files (e.g. stk.h) #STK_INC=/usr/local/include/stk # where to find the STK library (normally libstk.a) # (comment out STK_LIB if you don't use STK) #STK_LIB=/usr/local/lib/libstk.a ############################################################### # SndObj support # http://music.nuim.ie//musictec/SndObj # where to find the SndObj header files (e.g. sndobj.h) #SNDOBJ_INC=/usr/local/include/sndobj # where to find the SndObj library (normally libsndobj.a) # (comment out STK_LIB if you don't use SndObj) #SNDOBJ_LIB=/usr/local/lib/libsndobj.a ############################################################### # make flags (e.g. use multiprocessor) MFLAGS=-j 2 # user defined compiler flags UFLAGS += -ffast-math -mmacosx-version-min=10.9 # -march=native # user defined linker flags LDFLAGS += -mmacosx-version-min=10.9 # user defined optimization flags # for now, don't use -O3 !(Max will hang) OFLAGS += -Os -mtune=native # -ftree-vectorize # user defined debugging flags DFLAGS += # architecture-specific flags (optional) UFLAGS_ppc += -faltivec OFLAGS_ppc += DFLAGS_ppc += UFLAGS_i386 += OFLAGS_i386 += DFLAGS_i386 += UFLAGS_x86_64 += OFLAGS_x86_64 += DFLAGS_x86_64 += # list of architectures to build ARCH=i386 x86_64 # ppc ppc64 # SDK for 10.4 #OSXSDK=/Developer/SDKs/MacOSX10.4u.sdk flext-0-6-3/buildsys/mac/max/gnumake-gcc-ext.inc000066400000000000000000000007441446466241400215150ustar00rootroot00000000000000EXT=mxo ############################################## LDFLAGS += -bundle ############################################## OBJPATH=$(OUTPATH)/$(OUTSUB) # bundle name (build site) INSTTARGET=$(OBJPATH)/$(OUTNAME).$(EXT) # folder inside bundle (build site) TARGETPATH=$(INSTTARGET)/Contents/MacOS # file inside bundle (build site) TARGET=$(TARGETPATH)/$(OUTNAME) # post build target TARGETPOST=$(INSTTARGET)/Contents/Pkginfo $(INSTTARGET)/Contents/Pkginfo: echo "iLaX????" >> $@ flext-0-6-3/buildsys/mac/max/gnumake-gcc-flext.inc000066400000000000000000000005541446466241400220360ustar00rootroot00000000000000ifdef SHARED EXT=dylib else EXT=a endif ############################################## LDFLAGS += -dynamiclib ############################################## OBJPATH=$(OUTPATH)/$(OUTSUB) TARGETPATH=$(OBJPATH) TARGETNAME=$(OUTNAME).$(EXT) VERNAME=$(OUTNAME).$(FLEXTMAJOR).$(FLEXTMINOR).$(FLEXTMICRO).$(EXT) TARGET=$(TARGETPATH)/$(VERNAME) INSTTARGET=$(TARGET) flext-0-6-3/buildsys/mac/max/gnumake-gcc.inc000066400000000000000000000003641446466241400207150ustar00rootroot00000000000000DEFS += -DFLEXT_SYS=1 INCPATH += -I$(MAXSDKPATH)/max-includes -I$(MAXSDKPATH)/jit-includes -I$(MAXSDKPATH)/msp-includes LDFLAGS += -F$(MAXSDKPATH)/max-includes -framework MaxAPI LDFLAGS += -F$(MAXSDKPATH)/msp-includes -framework MaxAudioAPI flext-0-6-3/buildsys/mac/pd/000077500000000000000000000000001446466241400156545ustar00rootroot00000000000000flext-0-6-3/buildsys/mac/pd/config-gcc.def000066400000000000000000000041221446466241400203320ustar00rootroot00000000000000# where is the PD installation including source code? # (this should point to the main folder, which has a "src" (PD Vanilla) or "include" (PD extended) subfolder) PDPATH=/Applications/Pd-0.50-2.app/Contents/Resources # where is the PD executable? PDBIN=$(PDPATH)/bin/pd ############################################################### # prefix for flext installation # headers are in $(FLEXTPREFIX)/include/flext # libraries are in $(FLEXTPREFIX)/lib # build system is in $(FLEXTPREFIX)/lib/flext FLEXTPREFIX=/usr/local ############################################################### # where should the external be built? OUTPATH=pd-darwin # where should the external be installed? INSTPATH=$(PDPATH)/extra ############################################################### # STK (synthesis tool kit) support # http://ccrma.stanford.edu/software/stk # where to find the STK header files (e.g. stk.h) #STK_INC=/usr/local/include/stk # where to find the STK library (normally libstk.a) # (comment out STK_LIB if you don't use STK) #STK_LIB=/usr/local/lib/libstk.a ############################################################### # SndObj support # http://music.nuim.ie//musictec/SndObj # where to find the SndObj header files (e.g. sndobj.h) #SNDOBJ_INC=/usr/local/include/sndobj # where to find the SndObj library (normally libsndobj.a) # (comment out SNDOBJ_LIB if you don't use SndObj) #SNDOBJ_LIB=/usr/local/lib/libsndobj.a ############################################################### # make flags (e.g. use multiprocessor) MFLAGS=-j 2 # user defined compiler flags UFLAGS += -ffast-math -mmacosx-version-min=10.9 # -march=native # user defined linker flags LDFLAGS += -mmacosx-version-min=10.9 # user defined optimization flags OFLAGS += -O3 -mtune=native # user defined debugging flags DFLAGS += # architecture-specific flags (optional) UFLAGS_ppc += -faltivec OFLAGS_ppc += DFLAGS_ppc += UFLAGS_i386 += OFLAGS_i386 += DFLAGS_i386 += UFLAGS_x86_64 += OFLAGS_x86_64 += DFLAGS_x86_64 += # cross-compilation (optional) ARCH=i386 x86_64 # ppc ppc64 # SDK for 10.6 #OSXSDK=/Developer/SDKs/MacOSX10.6u.sdk flext-0-6-3/buildsys/mac/pd/gnumake-gcc-ext.inc000066400000000000000000000004651446466241400213330ustar00rootroot00000000000000EXT=pd_darwin #LDFLAGS += -bundle -bundle_loader $(PDBIN) # it seems we are having symbol name clashes with the following "new preferred method" # so we rather stick to the above "deprecated method" LDFLAGS += -dynamiclib -undefined dynamic_lookup TARGET=$(TARGETPATH)/$(TARGETNAME) INSTTARGET=$(TARGET) flext-0-6-3/buildsys/mac/pd/gnumake-gcc-flext.inc000066400000000000000000000003361446466241400216520ustar00rootroot00000000000000ifdef SHARED EXT=dylib else EXT=a endif LDFLAGS += -dynamiclib -flat_namespace -undefined suppress VERNAME=$(OUTNAME).$(FLEXTMAJOR).$(FLEXTMINOR).$(FLEXTMICRO).$(EXT) TARGET=$(TARGETPATH)/$(VERNAME) INSTTARGET=$(TARGET) flext-0-6-3/buildsys/mac/pd/gnumake-gcc.inc000066400000000000000000000003761446466241400205360ustar00rootroot00000000000000DEFS += -DFLEXT_SYS=2 -DPD INCPATH += -I$(PDPATH)/src -I$(PDPATH)/include -I$(PDPATH)/include/pd LIBPATH += -L$(PDPATH)/bin ############################################## OBJPATH=$(OUTPATH)/$(OUTSUB) TARGETPATH=$(OBJPATH) TARGETNAME=$(OUTNAME).$(EXT) flext-0-6-3/buildsys/nmake-ext.inc000066400000000000000000000000201446466241400170650ustar00rootroot00000000000000OUTNAME=$(NAME) flext-0-6-3/buildsys/nmake-flext.inc000066400000000000000000000000631446466241400174160ustar00rootroot00000000000000DEFS=$(DEFS) /DFLEXT_EXPORTS OUTNAME=$(FLEXTNAME) flext-0-6-3/buildsys/nmake-shlib.inc000066400000000000000000000000201446466241400173660ustar00rootroot00000000000000OUTNAME=$(NAME) flext-0-6-3/buildsys/nmake-sub.mak000066400000000000000000000016661446466241400170760ustar00rootroot00000000000000# include flext version number !include $(BUILDPATH)version.inc # general settings !include $(BUILDPATH)config-$(PLATFORM)-$(RTSYS)-$(COMPILER).txt ############################## # project-specific definitions # package info !if "$(PKGINFO)" != "" !include $(PKGINFO) !endif # special package settings !ifdef USRCONFIG !include $(USRCONFIG) !endif # package specific make stuff !ifdef USRMAKE !include $(USRMAKE) !endif ############################## # flext-specific definitions !include $(BUILDPATH)nmake.inc !include $(BUILDPATH)nmake-$(BUILDCLASS).inc ############################## # platform-specific make stuff !include $(BUILDPATH)$(PLATFORM)\$(RTSYS)\nmake-$(COMPILER).inc !include $(BUILDPATH)$(PLATFORM)\$(RTSYS)\nmake-$(COMPILER)-$(BUILDCLASS).inc ############################## # general make stuff !include $(BUILDPATH)$(PLATFORM)\nmake-$(COMPILER).inc !include $(BUILDPATH)$(PLATFORM)\nmake-$(COMPILER)-$(BUILDCLASS).inc flext-0-6-3/buildsys/nmake.inc000066400000000000000000000017331446466241400163030ustar00rootroot00000000000000############################################## # flext defines ############################################## CFLAGS=$(CFLAGS) $(UFLAGS) !ifdef DEBUG CFLAGS=$(CFLAGS) /D_DEBUG $(DFLAGS) !else CFLAGS=$(CFLAGS) /DNDEBUG $(OFLAGS) !endif !ifdef SHARED # --- shared --- DEFS=$(DEFS) /DFLEXT_SHARED !elseifdef THREADED # --- static multi-threaded --- DEFS=$(DEFS) /DFLEXT_THREADS !else # --- static single-threaded --- !endif ############################################## # name of flext library ############################################## !ifdef SHARED TYPEEXT=_ !else !ifdef THREADED TYPEEXT=_t !else TYPEEXT=_s !endif !endif !ifdef DEBUG MODEEXT=d !else !ifdef PROFILE MODEEXT=p !else MODEEXT= !ifdef SHARED TYPEEXT= !endif !endif !endif FLEXTNAME=flext-$(RTSYS)$(TYPEEXT)$(MODEEXT) ############################################## # product name and folder ############################################## !ifndef SRCDIR SRCDIR=. !endif OUTSUB=$(TARGETMODE)-$(TARGETTYPE) flext-0-6-3/buildsys/nmake.mak000066400000000000000000000053011446466241400162750ustar00rootroot00000000000000# required settings: # # PLATFORM - win/mac/lnx # RTSYS - pd/max # COMPILER - msvc/gcc/mingw/cygwin # BUILDPATH including trailing \ ############################################### # package info !ifndef PKGINFO PKGINFO=package.txt !endif !if "$(PKGINFO)" != "" !include $(PKGINFO) !endif !ifndef NAME !error NAME variable must be defined (name of target) !endif !ifndef SRCS !error SRCS variable must be defined (list of source files) !endif ############################################### # check variables !ifndef BUILDCLASS BUILDCLASS=ext !endif !ifndef BUILDMODE BUILDMODE=release !endif !ifndef BUILDTYPE BUILDTYPE=single !endif ############################## #!ifndef TARGETMODE #TARGETMODE=$(BUILDMODE) #!endif #!ifndef TARGETTYPE #TARGETTYPE=$(BUILDTYPE) #!endif ############################################### SYSCONFIG=$(BUILDPATH)config-$(PLATFORM)-$(RTSYS)-$(COMPILER).txt SYSDEFAULT=$(BUILDPATH)$(PLATFORM)\$(RTSYS)\config-$(COMPILER).def MAKE_OPTIONS=/NOLOGO /f $(BUILDPATH)nmake-sub.mak \ PLATFORM=$(PLATFORM) RTSYS=$(RTSYS) COMPILER=$(COMPILER) \ BUILDPATH=$(BUILDPATH) PKGINFO=$(PKGINFO) BUILDCLASS=$(BUILDCLASS) ############################################### !ifdef BUILDDIR USRCONFIG=config.txt USRDEFAULT=$(BUILDDIR)\config-$(PLATFORM).def USRMAKE=$(BUILDDIR)\nmake-$(PLATFORM)-$(COMPILER).inc MAKE_OPTIONS=$(MAKE_OPTIONS) $(MFLAGS) USRCONFIG=$(USRCONFIG) USRMAKE=$(USRMAKE) !endif ############################################### # include file describing default target dependencies !include $(BUILDPATH)\targets.inc !include $(BUILDPATH)\targets-$(BUILDCLASS).inc ############################################### .precious: $(SYSCONFIG) $(USRCONFIG) $(SYSCONFIG): $(SYSDEFAULT) @copy $** $@ @echo ------------------------------------------------------------------------- @echo A default system configuration file has been created. @echo Please edit $(SYSCONFIG) @echo to match your platform and start again. @echo ------------------------------------------------------------------------- @exit 1 !ifdef BUILDDIR $(USRCONFIG): $(USRDEFAULT) @copy $** $@ @echo ------------------------------------------------------------------------- @echo A default package configuration file has been created. @echo Please edit $(USRCONFIG) and start again. @echo ------------------------------------------------------------------------- @exit 1 $(USRDEFAULT) $(USRMAKE): @echo ------------------------------------------------------------------------- @echo Your combination of platform, system and compiler is not supported yet. @echo Required files: @echo $(USRDEFAULT) @echo and @echo $(USRMAKE) @echo ------------------------------------------------------------------------- @exit 1 !endif flext-0-6-3/buildsys/readme.txt000066400000000000000000000124571446466241400165200ustar00rootroot00000000000000flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ---------------------------------------------------------------------------- At the moment this is more like a sketchboard, but i'll promise to bring some order into it some fine day in the not too distant future. ---------------------------------------------------------------------------- Build scripts ============= Depending on platform the build process is run with build.sh or build.bat Arguments: PLATFORM SYSTEM COMPILER {TARGET} {definitions} PLATFORM: win / lnx / mac SYSTEM: pd / max COMPILER: msvc / gcc / mingw / cygwin TARGET: (default is all) all, build - build package in default style install - install package clean - clean build products config - test if configuration needs refreshing or build-MODE-TYPE install-MODE-TYPE clean-MODE-TYPE with MODE: default, all, release, debug, profile TYPE: default, all, single, multi, shared Additional definitions can be passed to the make program like "PKGINFO=info.txt" (defines new filename for package information) or "PKGINFO=" (package information will be skipped - only for config target) For more macro names, see below For each of the supported combinations of PLATFORM, SYSTEM and COMPILER a MAKE program has been chosen, normally the one that comes with the compiler. For gcc it is GNU make (gnumake) For msvc it is Microsoft make (nmake) Package info (package.txt) ========================== Package information contains vital information for the build process. Obligatory are only: NAME: resulting filename of the build product SRCS: list of source files Normally also used are: HDRS: used header files, which SRCS files are dependent upon SRCDIR: source folder (relative to project folder), default is . Other settings: PRECOMPILE: prefix header file (in SRCDIR) for all source files, will be precompiled if supported by the compiler BUILDCLASS: can currently be flext or ext, default is ext. flext will build the flext system ext will build a flext-based external BUILDMODE: release or debug, default is release if release, optimization flags will be used if debug, debug information will be generated if profile, profiling information will be generated (with debug info and optimization) BUILDTYPE: single, multi or shared, default is single if single, it will be linked against the single-threaded static flext library if multi, it will be linked against the multi-threaded static flext library if shared, it will be linked against the shared flext library BUILDDIR: relative folder with additional build settings Additional build settings (BUILDDIR) ==================================== If BUILDDIR is defined, all PLATFORM-SYSTEM-COMPILER combinations to support must are mirrored by the respective .def and .inc files in the BUILDDIR. config-PLATFORM.def files (e.g. config-lnx.def) : These files can contain additional macro definitions, that are private to the project. The definitions should be strictly in the form SETTING=value, without any make-specific macros etc. The .def files work as templates that get copied to a user-editable config.txt file when the build process is first started. MAKE-PLATFORM-COMPILER.inc files (e.g. gnumake-lnx-gcc.inc or nmake-win-msvc.inc): These files (which are no considered to be edited by the user) can contain specific modifications to compiler flags, include file paths etc. For gnumake this would e.g. be INCPATH += -I/usr/local/include/python2.3 for nmake or bmake e.g. INCPATH = $(INCPATH) -I"c:\program files\Python2.3\include" Structure of build system ========================= The build system has several levels of information, which are evaluated in the following order (see also buildsys/MAKE-sub.mak) Project level: - PKGINFO file (e.g. package.txt) - USRCONFIG file (e.g. config.txt) - USRMAKE file (e.g. build/gnumake-lnx-gcc.inc) General definitions (in buildsys): - MAKE.inc (e.g. buildsys/gnumake.inc) contains evaluation of flext library name, build directory etc. - MAKE-BUILDCLASS.inc (e.g. buildsys/gnumake-ext.inc) contains some more flag settings Real-time-system-dependent definitions (in buildsys/PLATFORM/SYSTEM): - MAKE-COMPILER.inc (e.g. buildsys/lnx/pd/gnumake-gcc.inc) contains general real-time-system dependent info (e.g. paths, FLEXT_SYS setting) - MAKE-COMPILER-BUILDCLASS.inc (e.g. buildsys/lnx/pd/gnumake-gcc-ext.inc) contains specific real-time-system dependent info (e.g. extension of binary) Platform-dependent definitions (in buildsys/PLATFORM): - MAKE-COMPILER.inc (e.g. buildsys/lnx/gnumake-gcc.inc) contains general platform-specific flags - MAKE-COMPILER-BUILDCLASS.inc (e.g. buildsys/lnx/gnumake-gcc-ext.inc) contains the actual make targets (_build_,_clean_ and _install_) Macro names =============== PKGINFO - filename for package information (must reside in project folder) UFLAGS - user defined compiler flags OFLAGS - user defined optimization flags (not used in debug builds) CFLAGS - compiler flags LDFLAGS - linker flags INCPATH - include file path (must come with e.g. -I ) LIBPATH - library path (must come with e.g. -L ) LIBS - libraries to link in (must come with e.g. -l ) flext-0-6-3/buildsys/targets-ext.inc000066400000000000000000000023271446466241400174570ustar00rootroot00000000000000build-default-default: build-$(BUILDMODE)-$(BUILDTYPE) build-all-default: build-all-$(BUILDTYPE) build-release-default: build-release-$(BUILDTYPE) build-debug-default: build-debug-$(BUILDTYPE) build-profile-default: build-profile-$(BUILDTYPE) build-default-all: build-$(BUILDMODE)-all build-default-single: build-$(BUILDMODE)-single build-default-multi: build-$(BUILDMODE)-multi build-default-shared: build-$(BUILDMODE)-shared install-default-default: install-$(BUILDMODE)-$(BUILDTYPE) install-all-default: install-all-$(BUILDTYPE) install-release-default: install-release-$(BUILDTYPE) install-debug-default: install-debug-$(BUILDTYPE) install-default-all: install-$(BUILDMODE)-all install-default-single: install-$(BUILDMODE)-single install-default-multi: install-$(BUILDMODE)-multi install-default-shared: install-$(BUILDMODE)-shared clean-default-default: clean-$(BUILDMODE)-$(BUILDTYPE) clean-all-default: clean-all-$(BUILDTYPE) clean-release-default: clean-release-$(BUILDTYPE) clean-debug-default: clean-debug-$(BUILDTYPE) clean-default-all: clean-$(BUILDMODE)-all clean-default-single: clean-$(BUILDMODE)-single clean-default-multi: clean-$(BUILDMODE)-multi clean-default-shared: clean-$(BUILDMODE)-shared flext-0-6-3/buildsys/targets-flext.inc000066400000000000000000000017341446466241400200020ustar00rootroot00000000000000build-default-default: build-all-all build-all-default: build-all-all build-release-default: build-release-all build-debug-default: build-debug-all build-profile-default: build-profile-all build-default-all: build-all-all build-default-single: build-all-single build-default-multi: build-all-multi build-default-shared: build-all-shared install-default-default: install-all-all install-all-default: install-all-all install-release-default: install-release-all install-debug-default: install-debug-all install-default-all: install-all-all install-default-single: install-all-single install-default-multi: install-all-multi install-default-shared: install-all-shared clean-default-default: clean-all-all clean-all-default: clean-all-all clean-release-default: clean-release-all clean-debug-default: clean-debug-all clean-default-all: clean-all-all clean-default-single: clean-all-single clean-default-multi: clean-all-multi clean-default-shared: clean-all-shared flext-0-6-3/buildsys/targets-shlib.inc000066400000000000000000000023271446466241400177600ustar00rootroot00000000000000build-default-default: build-$(BUILDMODE)-$(BUILDTYPE) build-all-default: build-all-$(BUILDTYPE) build-release-default: build-release-$(BUILDTYPE) build-debug-default: build-debug-$(BUILDTYPE) build-profile-default: build-profile-$(BUILDTYPE) build-default-all: build-$(BUILDMODE)-all build-default-single: build-$(BUILDMODE)-single build-default-multi: build-$(BUILDMODE)-multi build-default-shared: build-$(BUILDMODE)-shared install-default-default: install-$(BUILDMODE)-$(BUILDTYPE) install-all-default: install-all-$(BUILDTYPE) install-release-default: install-release-$(BUILDTYPE) install-debug-default: install-debug-$(BUILDTYPE) install-default-all: install-$(BUILDMODE)-all install-default-single: install-$(BUILDMODE)-single install-default-multi: install-$(BUILDMODE)-multi install-default-shared: install-$(BUILDMODE)-shared clean-default-default: clean-$(BUILDMODE)-$(BUILDTYPE) clean-all-default: clean-all-$(BUILDTYPE) clean-release-default: clean-release-$(BUILDTYPE) clean-debug-default: clean-debug-$(BUILDTYPE) clean-default-all: clean-$(BUILDMODE)-all clean-default-single: clean-$(BUILDMODE)-single clean-default-multi: clean-$(BUILDMODE)-multi clean-default-shared: clean-$(BUILDMODE)-shared flext-0-6-3/buildsys/targets.inc000066400000000000000000000116751446466241400166670ustar00rootroot00000000000000all: build build: build-default-default profile: build-profile-default clean: clean-default-default install: install-default-default ########################################################### build-all-all: build-release-all build-debug-all build-release-all: build-release-single build-release-multi build-release-shared build-debug-all: build-debug-single build-debug-multi build-debug-shared build-profile-all: build-profile-single build-profile-multi build-profile-shared build-all-single: build-release-single build-debug-single build-all-multi: build-release-multi build-debug-multi build-all-shared: build-release-shared build-debug-shared ################################################### install-all-all: install-release-all install-debug-all install-release-all: install-release-single install-release-multi install-release-shared install-debug-all: install-debug-single install-debug-multi install-debug-shared install-profile-all: install-profile-single install-profile-multi install-profile-shared install-all-single: install-release-single install-debug-single install-all-multi: install-release-multi install-debug-multi install-all-shared: install-release-shared install-debug-shared ################################################### clean-all-all: clean-release-all clean-debug-all clean-release-all: clean-release-single clean-release-multi clean-release-shared clean-debug-all: clean-debug-single clean-debug-multi clean-debug-shared clean-profile-all: clean-profile-single clean-profile-multi clean-profile-shared clean-all-single: clean-release-single clean-debug-single clean-all-multi: clean-release-multi clean-debug-multi clean-all-shared: clean-release-shared clean-debug-shared ########################################################### build-release-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=single _build_ build-debug-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=single DEBUG=1 _build_ build-profile-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=single PROFILE=1 _build_ build-release-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=multi THREADED=1 _build_ build-debug-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=multi THREADED=1 DEBUG=1 _build_ build-profile-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=multi THREADED=1 PROFILE=1 _build_ build-release-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=shared SHARED=1 _build_ build-debug-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=shared SHARED=1 DEBUG=1 _build_ build-profile-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=shared SHARED=1 PROFILE=1 _build_ ########################################################### install-release-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=single _install_ install-debug-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=single DEBUG=1 _install_ install-profile-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=single PROFILE=1 _install_ install-release-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=multi THREADED=1 _install_ install-debug-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=multi THREADED=1 DEBUG=1 _install_ install-profile-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=multi THREADED=1 PROFILE=1 _install_ install-release-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=shared SHARED=1 _install_ install-debug-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=shared SHARED=1 DEBUG=1 _install_ install-profile-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=shared SHARED=1 PROFILE=1 _install_ ########################################################### clean-release-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=single _clean_ clean-debug-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=single DEBUG=1 _clean_ clean-profile-single: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=single PROFILE=1 _clean_ clean-release-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=multi THREADED=1 _clean_ clean-debug-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=multi THREADED=1 DEBUG=1 _clean_ clean-profile-multi: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=multi THREADED=1 PROFILE=1 _clean_ clean-release-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=release TARGETTYPE=shared SHARED=1 _clean_ clean-debug-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=debug TARGETTYPE=shared SHARED=1 DEBUG=1 _clean_ clean-profile-shared: config $(MAKE) $(MAKE_OPTIONS) TARGETMODE=profile TARGETTYPE=shared SHARED=1 PROFILE=1 _clean_ ########################################################### config: $(USRMAKE) $(SYSCONFIG) $(USRCONFIG) flext-0-6-3/buildsys/version.inc000066400000000000000000000000471446466241400166720ustar00rootroot00000000000000FLEXTMAJOR=0 FLEXTMINOR=6 FLEXTMICRO=2 flext-0-6-3/buildsys/win/000077500000000000000000000000001446466241400153065ustar00rootroot00000000000000flext-0-6-3/buildsys/win/gnumake-cygwin-ext.inc000066400000000000000000000015651446466241400215330ustar00rootroot00000000000000# build class specific settings INCPATH += -I$(FLEXTINC) LIBPATH += -L$(FLEXTLIB) -L$(FLEXTSHLIB) LIBS += -l$(FLEXTNAME) ############################################## # default target _build_: $(TARGET) $(CSRCS) $(CPPSRCS): $(patsubst %,$(SRCDIR)/%,$(HDRS)) touch $@ $(TARGETPATH): -mkdir -p $@ $(TARGETPATH)/%.opp : $(SRCDIR)/%.cpp $(CXX) -c $(CFLAGS) $(DEFS) $(INCPATH) $< -o $@ $(TARGETPATH)/%.o : $(SRCDIR)/%.c $(CC) -c $(CFLAGS) $(DEFS) $(INCPATH) $< -o $@ $(TARGET) :: $(TARGETPATH) $(TARGET) :: $(COBJS) $(CPPOBJS) $(CXX) $(LDFLAGS) $(LIBPATH) -o $@ $(COBJS) $(CPPOBJS) $(LIBS) $(SYSLIBS) strip --strip-unneeded $@ chmod 755 $@ ############################################## _clean_: rm $(COBJS) $(CPPOBJS) $(TARGET) ############################################## $(INSTPATH): -mkdir -p $(INSTPATH) _install_: $(INSTPATH) install $(TARGET) $(INSTPATH) flext-0-6-3/buildsys/win/gnumake-cygwin-flext.inc000066400000000000000000000020411446466241400220430ustar00rootroot00000000000000# build class specific settings ############################################## # default target _build_: $(TARGET) $(CSRCS) $(CPPSRCS): $(patsubst %,$(SRCDIR)/%,$(HDRS)) touch $@ $(TARGETPATH): -mkdir -p $@ $(TARGETPATH)/%.opp : $(SRCDIR)/%.cpp $(CXX) -c $(CFLAGS) $(DEFS) $(INCPATH) $< -o $@ $(TARGETPATH)/%.o : $(SRCDIR)/%.c $(CC) -c $(CFLAGS) $(DEFS) $(INCPATH) $< -o $@ $(TARGET) :: $(TARGETPATH) $(TARGET) :: $(COBJS) $(CPPOBJS) ifdef SHARED $(CXX) $(LDFLAGS) $(LIBPATH) -o $@ $(COBJS) $(CPPOBJS) $(LIBS) $(SYSLIBS) chmod 755 $@ strip --strip-unneeded $@ else $(AR) rc $@ $(COBJS) $(CPPOBJS) endif ############################################## _clean_: rm $(COBJS) $(CPPOBJS) $(TARGET) ############################################## ifdef SHARED FLEXTLIBINST=$(FLEXTSHLIB) else FLEXTLIBINST=$(FLEXTLIB) endif $(FLEXTINC): -mkdir -p $(FLEXTINC) $(FLEXTLIBINST): -mkdir -p $(FLEXTLIBINST) _install_: $(FLEXTINC) $(FLEXTLIBINST) install $(TARGET) $(FLEXTLIBINST) install $(patsubst %,$(SRCDIR)/%,$(HDRS) $(SRCS)) $(FLEXTINC) flext-0-6-3/buildsys/win/gnumake-cygwin.inc000066400000000000000000000015031446466241400207250ustar00rootroot00000000000000############################################## OBJPATH=$(OUTPATH)/$(OUTSUB) TARGETPATH=$(OBJPATH) TARGET=$(TARGETPATH)/$(OUTNAME).$(EXT) INCPATH += -I/usr/include ############################################## CFLAGS += -mno-cygwin -include /usr/include/stdlib.h LDFLAGS += -shared -mno-cygwin # default Windows flags as defined from VC IDE CFLAGS += -DWIN32 -D_WINDOWS ############################################## ifdef DEBUG CFLAGS += -g else ifdef PROFILE CFLAGS += -g -pg LDFLAGS += -pg else LDFLAGS += -Wl,-S endif endif ############################################## CSRCS=$(patsubst %.c,$(SRCDIR)/%.c,$(filter %.c,$(SRCS))) CPPSRCS=$(patsubst %.cpp,$(SRCDIR)/%.cpp,$(filter %.cpp,$(SRCS))) COBJS=$(patsubst %.c,$(OBJPATH)/%.o,$(filter %.c,$(SRCS))) CPPOBJS=$(patsubst %.cpp,$(OBJPATH)/%.opp,$(filter %.cpp,$(SRCS))) flext-0-6-3/buildsys/win/gnumake-gcc-ext.inc000066400000000000000000000013671446466241400207670ustar00rootroot00000000000000# build class specific settings INCPATH += -I$(FLEXTINC) LIBPATH += -L$(FLEXTLIB) LIBS += -l$(FLEXTNAME) # common compilation stuff include $(BUILDPATH)$(PLATFORM)/gnumake-gcc-targets.inc ##### linking ################### $(TARGET) :: $(OBJPATH) $(TARGETPATH) $(TARGET) :: $(PRECOMDST) $(COBJS) $(CPPOBJS) $(CXX) $(LDFLAGS) $(LIBPATH) -o $@ $(COBJS) $(CPPOBJS) $(LIBS) ifdef DEBUG else ifdef PROFILE else strip -x $@ endif endif chmod 755 $@ ifdef TARGETPOST $(TARGET) :: $(TARGETPOST) endif ################################### # Attention: $@ doesn't work for paths with spaces.... $(INSTPATH): -mkdir -p $(INSTPATH) _install_:: $(INSTPATH) # copy plain file or whole bundle cp -R $(INSTTARGET) $(INSTPATH) flext-0-6-3/buildsys/win/gnumake-gcc-flext.inc000066400000000000000000000025221446466241400213030ustar00rootroot00000000000000# build class specific settings #ifdef SHARED #LDFLAGS += -install_name $(FLEXTLIB)/$(TARGETNAME) #LDFLAGS += -current_version $(FLEXTMAJOR).$(FLEXTMINOR).$(FLEXTMICRO) #LDFLAGS += -compatibility_version $(FLEXTMAJOR).$(FLEXTMINOR) #LDFLAGS += -preload -seg1addr 0xd0000000 #endif # common compilation stuff include $(BUILDPATH)$(PLATFORM)/gnumake-gcc-targets.inc ##### linking ################### $(TARGET) :: $(OBJPATH) $(TARGETPATH) $(TARGET) :: $(PRECOMDST) $(COBJS) $(CPPOBJS) ifdef SHARED $(CXX) $(LDFLAGS) $(LIBPATH) -o $@ $(COBJS) $(CPPOBJS) $(LIBS) ifdef DEBUG else ifdef PROFILE else strip -x $@ endif endif chmod 755 $@ else $(AR) rc $@ $(COBJS) $(CPPOBJS) endif ifdef TARGETPOST $(TARGET) :: $(TARGETPOST) endif ################################### $(FLEXTINC): -mkdir -p $@ $(FLEXTLIB): -mkdir -p $@ _install_: $(FLEXTINC) $(FLEXTLIB) # --- install as dynamic library --- install $(TARGET) $(FLEXTLIB) ifdef VERNAME ln -sf $(VERNAME) $(FLEXTLIB)/$(TARGETNAME) endif install $(patsubst %,$(SRCDIR)/%,$(HDRS) $(SRCS)) $(FLEXTINC) # transfer build system # cp -rf buildsys $(FLEXTSYS) # install build.sh $(FLEXTSYS) # chmod -R a+rx $(FLEXTSYS) # make convenience script # echo bash $(FLEXTSYS)/build.sh $$\* > $(FLEXTBIN)/flext-build.sh # chmod a+rx $(FLEXTBIN)/flext-build.sh flext-0-6-3/buildsys/win/gnumake-gcc-targets.inc000066400000000000000000000025711446466241400216360ustar00rootroot00000000000000############################################## CSRCS := $(patsubst %.c,$(SRCDIR)/%.c,$(filter %.c,$(SRCS))) CPPSRCS := $(patsubst %.cpp,$(SRCDIR)/%.cpp,$(filter %.cpp,$(SRCS))) COBJS := $(patsubst %.c,$(OBJPATH)/%.o,$(filter %.c,$(SRCS))) CPPOBJS := $(patsubst %.cpp,$(OBJPATH)/%.opp,$(filter %.cpp,$(SRCS))) ############################################## # default target _build_: $(TARGET) $(CSRCS) $(CPPSRCS): $(patsubst %,$(SRCDIR)/%,$(HDRS)) touch $@ # Attention: $@ doesn't work for paths with spaces.... $(OBJPATH): -mkdir -p $(OBJPATH) # Attention: $@ doesn't work for paths with spaces.... $(TARGETPATH): -mkdir -p $(TARGETPATH) ##### precompiled header file ################### ifdef PRECOMPILE PRECOMSRC := $(SRCDIR)/$(PRECOMPILE) else PRECOMSRC := $(FLEXTINC)/flext.h endif ifdef PRECOMSRC PRECOMDST := $(OBJPATH)/$(notdir $(PRECOMSRC)).gch PRECOMINC := -I $(OBJPATH) endif $(PRECOMDST) : $(PRECOMSRC) $(patsubst %,$(SRCDIR)/%,$(HDRS)) -mkdir -p $(dir $@) $(CXX) -c $(DEFS) $(INCPATH) $(PRECOMSRC) -o $@ $(OBJPATH)/%.opp : $(SRCDIR)/%.cpp -mkdir -p $(dir $@) $(CXX) -c $(CFLAGS) $(DEFS) $(PRECOMINC) $(INCPATH) $^ -o $@ $(OBJPATH)/%.o : $(SRCDIR)/%.c -mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(DEFS) $(INCPATH) $^ -o $@ ############################################## _clean_: -rm -r $(TARGETPATH) -rm -r $(OBJPATH) ############################################## flext-0-6-3/buildsys/win/gnumake-gcc.inc000066400000000000000000000014651446466241400201700ustar00rootroot00000000000000############################################## ifdef LOCKFREEPATH INCPATH += -I$(LOCKFREEPATH) endif ifdef ATOMICOPSPATH INCPATH += -I$(ATOMICOPSPATH) endif ifdef SNDOBJ_LIB INCPATH += -I$(SNDOBJ_INC) LIBPATH += -L$(SNDOBJ_LIB) endif ifdef STK_LIB INCPATH += -I$(STK_INC) LIBPATH += -L$(STK_LIB) endif ############################################## ifndef FLEXTLIB FLEXTLIB := $(FLEXTPREFIX)/lib endif ifndef FLEXTINC FLEXTINC := $(FLEXTPREFIX)/include/flext endif ifndef FLEXTSYS FLEXTSYS := $(FLEXTPREFIX)/lib/flext endif ############################################## LDFLAGS += -dynamic ############################################## ifdef DEBUG CFLAGS += -g LDFLAGS += -g else ifdef PROFILE CFLAGS += -g LDFLAGS += -g else LDFLAGS += -Wl,-S endif endif flext-0-6-3/buildsys/win/gnumake-mingw-ext.inc000066400000000000000000000023621446466241400213500ustar00rootroot00000000000000# build class specific settings INCPATH += -I$(FLEXTINC) LIBPATH += -L$(FLEXTLIB) -L$(FLEXTSHLIB) ifdef SHARED LIBS += $(FLEXTSHLIB)/lib$(FLEXTNAME).dll else LIBS += -l$(FLEXTNAME) endif ifndef SHARED ifdef SNDOBJ LIBS += -lSndObj endif ifdef STK LIBS += -lStk endif endif ############################################## # default target _build_: $(TARGET) #$(CSRCS) $(CPPSRCS): $(patsubst %,$(SRCDIR)/%,$(HDRS)) # touch $@ $(OUTPATH): -mkdir $(subst /,\,$@) $(TARGETPATH): $(OUTPATH) -mkdir $(subst /,\,$@) $(TARGETPATH)/%.opp : $(SRCDIR)/%.cpp $(CXX) -c $(CFLAGS) $(DEFS) $(subst \,/,$(INCPATH)) $< -o $(subst /,\,$@) $(TARGETPATH)/%.o : $(SRCDIR)/%.c $(CC) -c $(CFLAGS) $(DEFS) $(subst \,/,$(INCPATH)) $< -o $(subst /,\,$@) $(TARGET) :: $(TARGETPATH) $(TARGET) :: $(COBJS) $(CPPOBJS) $(CXX) $(LDFLAGS) $(subst \,/,$(LIBPATH)) -o $(subst /,\,$@) $(subst /,\,$(COBJS) $(CPPOBJS) $(LIBS) $(SYSLIBS)) -strip --strip-unneeded $@ ############################################## _clean_: -del /q $(subst /,\,$(TARGETPATH)/*.*) > nul -rmdir /q $(subst /,\,$(TARGETPATH)) > nul ############################################## _install_: @if not exist $(subst /,\,$(INSTPATH)) -mkdir $(subst /,\,$(INSTPATH)) copy $(subst /,\,$(TARGET) $(INSTPATH)) flext-0-6-3/buildsys/win/gnumake-mingw-flext.inc000066400000000000000000000024261446466241400216730ustar00rootroot00000000000000# build class specific settings ############################################## # default target _build_: $(TARGET) #$(CSRCS) $(CPPSRCS): $(patsubst %,$(SRCDIR)/%,$(HDRS)) # touch $@ $(OUTPATH): -mkdir $(subst /,\,$@) $(TARGETPATH): $(OUTPATH) -mkdir $(subst /,\,$@) $(TARGETPATH)/%.opp : $(SRCDIR)/%.cpp $(CXX) -c $(CFLAGS) $(DEFS) $(subst \,/,$(INCPATH)) $< -o $(subst /,\,$@) $(TARGETPATH)/%.o : $(SRCDIR)/%.c $(CC) -c $(CFLAGS) $(DEFS) $(subst \,/,$(INCPATH)) $< -o $(subst /,\,$@) $(TARGET) :: $(TARGETPATH) $(TARGET) :: $(COBJS) $(CPPOBJS) ifdef SHARED $(CXX) $(LDFLAGS) $(LIBPATH) -o $(subst /,\,$@) $(subst /,\,$(COBJS) $(CPPOBJS) $(LIBS)) -strip --strip-unneeded $@ else $(AR) rc $@ $(COBJS) $(CPPOBJS) endif ############################################## _clean_: -del /q $(subst /,\,$(TARGETPATH)/*.*) > nul -rmdir /q $(subst /,\,$(TARGETPATH)) > nul ############################################## ifdef SHARED FLEXTLIBINST=$(FLEXTSHLIB) else FLEXTLIBINST=$(FLEXTLIB) endif _install_:: @if not exist $(subst /,\,$(FLEXTINC)) -mkdir $(subst /,\,$(FLEXTINC)) @if not exist $(subst /,\,$(FLEXTLIBINST)) -mkdir $(subst /,\,$(FLEXTLIBINST)) copy $(subst /,\,$(TARGET) $(FLEXTLIBINST)) -for %%i in ($(HDRS) $(SRCS)) do @copy $(SRCDIR)\%%i $(subst /,\,$(FLEXTINC)) > nul flext-0-6-3/buildsys/win/gnumake-mingw.inc000066400000000000000000000014021446466241400205440ustar00rootroot00000000000000############################################## OBJPATH=$(OUTPATH)\$(OUTSUB) TARGETPATH=$(OBJPATH) TARGET=$(TARGETPATH)\$(OUTNAME).$(EXT) ############################################## CFLAGS += -mms-bitfields LDFLAGS += -shared # default Windows flags as defined from VC IDE CFLAGS += -DWIN32 -D_WINDOWS ############################################## ifdef DEBUG CFLAGS += -g else ifdef PROFILE CFLAGS += -g -pg LDFLAGS += -pg else LDFLAGS += -Wl,-S endif endif ############################################## CSRCS=$(patsubst %.c,$(SRCDIR)/%.c,$(filter %.c,$(SRCS))) CPPSRCS=$(patsubst %.cpp,$(SRCDIR)/%.cpp,$(filter %.cpp,$(SRCS))) COBJS=$(patsubst %.c,$(OBJPATH)/%.o,$(filter %.c,$(SRCS))) CPPOBJS=$(patsubst %.cpp,$(OBJPATH)/%.opp,$(filter %.cpp,$(SRCS))) flext-0-6-3/buildsys/win/max/000077500000000000000000000000001446466241400160735ustar00rootroot00000000000000flext-0-6-3/buildsys/win/max/config-cygwin.def000066400000000000000000000042411446466241400213170ustar00rootroot00000000000000# where is the Max/MSP application? MAXAPPPATH=/cygdrive/c/program\ files/MaxMSP\ 4.5 # where are the Max/MSP common files? MAXCOMPATH=/cygdrive/c/program\ files/common\ files/Cycling\ \'74 # where are the Max/MSP SDK header files? # you should have the latest version! MAXSDKPATH=$(MAXAPPPATH)/maxmspsdk_win/4.5\ headers/c74support ############################################################### ############################################################### # where do/should the flext headers reside/be built? FLEXTINC=$(MAXCOMPATH)/flext # where do/should the flext static libraries reside/be built? FLEXTLIB=$(FLEXTINC) # where do/should the flext shared libraries reside/be built? # (a good place is the MaxMSP program folder) FLEXTSHLIB=$(MAXAPPPATH) ############################################################### # where should the external be built? # (path for temporary files) OUTPATH=max-cygwin # where should the external be installed? INSTPATH=$(MAXCOMPATH)/externals/flext # where should the initialization files be installed? INITPATH=$(MAXCOMPATH)/init # where should the help files be installed? HELPPATH=$(MAXAPPPATH)/max-help/flext ############################################################### # where is the STK installation? # (uncomment the line with # to disable STK support) # -------------------------------------------------------------------- # In order to use STK you must have a libstk.a library # #STK=c:\data\prog\audio\stk # where is the Sndobjs installation? # (uncomment the line with # to disable SNDOBJ support) # -------------------------------------------------------------------- # Please be sure to delete an eventual m_pd.h file from the SNDOBJ include folder!! # The shared flext library links to the libsndobj.a file from the SNDOBJ distribution. # #SNDOBJ=c:\data\prog\audio\sndobj ############################################################### # make flags (e.g. use multiprocessor) #MFLAGS=-j 2 # user defined compiler flags # (check if they match your system!) UFLAGS=-msse -mfpmath=sse -ffast-math # user defined optimization flags # (check if they match your system!) OFLAGS=-O3 # optimizations for Pentium 4 OFLAGS+=-march=pentium4 flext-0-6-3/buildsys/win/max/config-mingw.def000066400000000000000000000040521446466241400211400ustar00rootroot00000000000000# where are the Max/MSP SDK header files? # you should have the latest version! MAXSDKPATH="%ProgramFiles%\MaxMSP 4.5/maxmspsdk_win/4.5 headers/c74support" ############################################################### # where do/should the flext headers reside/be built? FLEXTINC="%CommonProgramFiles%/Cycling '74/flext" # where do/should the flext static libraries reside/be built? FLEXTLIB=$(FLEXTINC) # where do/should the flext shared libraries reside/be built? # (a good place is the MaxMSP program folder) FLEXTSHLIB="%ProgramFiles%\MaxMSP 4.5" ############################################################### # where should the external be built? # (path for temporary files) OUTPATH=max-mingw # where should the external be installed? INSTPATH="%CommonProgramFiles%/Cycling '74/externals/flext" # where should the initialization files be installed? INITPATH="%CommonProgramFiles%/Cycling '74/init" # where should the help files be installed? HELPPATH="%ProgramFiles%/MaxMSP 4.5/max-help/flext" ############################################################### # where is the STK installation? # (uncomment the line with # to disable STK support) # -------------------------------------------------------------------- # In order to use STK you must have an Stk.obj file # made with mingw # g++ -c -mno-cygwin -O3 -I ../include Stk.cpp -o Stk.obj # #STK=c:\data\prog\audio\stk # where is the Sndobjs installation? # (uncomment the line with # to disable SNDOBJ support) # -------------------------------------------------------------------- # Please be sure to delete an eventual m_pd.h file from the SNDOBJ include folder!! # The shared flext library links to the libsndobj.a library. # #SNDOBJ=c:\data\prog\audio\sndobj ############################################################### # make flags (e.g. use multiprocessor) #MFLAGS=-j 2 # user defined compiler flags # (check if they match your system!) UFLAGS=-msse -ffast-math # user defined optimization flags # (check if they match your system!) OFLAGS=-O3 # optimizations for Pentium 4 OFLAGS+=-march=pentium4 flext-0-6-3/buildsys/win/max/config-msvc.def000066400000000000000000000055641446466241400210000ustar00rootroot00000000000000# where are the Max/MSP SDK header files? # you should have the latest version! MAXSDKPATH="%ProgramFiles%\MaxMSP 4.5\maxmspsdk_win\4.5 headers\c74support" # where is MS VC++? # (not necessary if the build is run with the compiler environment) # MSVCPATH="%ProgramFiles%\Microsoft Visual Studio .NET 2003\Vc7" ############################################################### # where do/should the flext headers reside/be built? FLEXTINC="%CommonProgramFiles%\Cycling '74\flext" # where do/should the flext static libraries reside/be built? FLEXTLIB=$(FLEXTINC) # where do/should the flext shared libraries reside/be built? # (a good place is the MaxMSP program folder) FLEXTSHLIB="%ProgramFiles%\MaxMSP 4.5" ############################################################### # where should the external be built? # (path for temporary files) OUTPATH=max-msvc # where should the external be installed? INSTPATH="%CommonProgramFiles%\Cycling '74\externals\flext" # where should the initialization files be installed? INITPATH="%CommonProgramFiles%\Cycling '74\init" # where should the help files be installed? HELPPATH="%ProgramFiles%\MaxMSP 4.5\max-help\flext" ############################################################### # where is the STK installation? # (uncomment the line with # to disable STK support) # -------------------------------------------------------------------- # In order to use STK you must have an stk.lib library # Using MSVC you can build it as following (from the STK main folder): # cl /c /GR /EHsc /Iinclude /MT /Ox src\*.cpp # (in case you define DYNAMIC=1 below, omit the /MT flag and set /MD instead) # (you will get errors for some files, you can ignore them in the flext context) # lib *.obj /out:stk.lib # # where to find the STK header files (e.g. stk.h) #STK_INC=%HOMEDRIVE%\%HOMEPATH%\stk\include # where to find the STK library (normally stk.lib) # (comment out STK_LIB if you don't use STK) #STK_LIB=%HOMEDRIVE%\%HOMEPATH%\stk\stk.lib # where is the Sndobjs installation? # (uncomment the line with # to disable SNDOBJ support) # -------------------------------------------------------------------- # Please be sure to delete an eventual m_pd.h file from the SNDOBJ include folder!! # Flext must be compiled with the same compiler version as the SNDOBJ lib (default MSVC6) # # where to find the SndObj header files (e.g. SndObj.h) #SNDOBJ_INC=%HOMEDRIVE%\%HOMEPATH%\SndObj\include # where to find the SndObj library (normally SndObj.lib) # (comment out SNDOBJ_LIB if you don't use SndObj) #SNDOBJ_LIB=%HOMEDRIVE%\%HOMEPATH%\SndObj\lib\SndObj.lib ############################################################### # some user-definable flags # (check if they match your system!) OFLAGS=/Ox # optimizations for Pentium 4 #OFLAGS=$(OFLAGS) /G6 /arch:SSE # uncomment to link against dynamic C runtime libraries # (that's ok if you compile with VC++ 7.0 and 7.1) DYNAMIC=1 flext-0-6-3/buildsys/win/max/gnumake-cygwin-ext.inc000066400000000000000000000000101446466241400223000ustar00rootroot00000000000000EXT=mxe flext-0-6-3/buildsys/win/max/gnumake-cygwin-flext.inc000066400000000000000000000000471446466241400226340ustar00rootroot00000000000000ifdef SHARED EXT=dll else EXT=a endif flext-0-6-3/buildsys/win/max/gnumake-cygwin.inc000066400000000000000000000006641446466241400215210ustar00rootroot00000000000000DEFS += -DFLEXT_SYS=1 # fpack-struct should align to 2 bytes... rely on the SDK to specify that CFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x501 -DWIN_VERSION -DWIN_EXT_VERSION INCPATH += -I$(MAXSDKPATH)/max-includes -I$(MAXSDKPATH)/jit-includes -I$(MAXSDKPATH)/msp-includes LIBPATH += -L$(MAXSDKPATH)/max-includes -L$(MAXSDKPATH)/jit-includes -L$(MAXSDKPATH)/msp-includes # these are both in MAXSDKPATH SYSLIBS += -lMaxAPI -lMaxAudio flext-0-6-3/buildsys/win/max/gnumake-mingw-ext.inc000066400000000000000000000000101446466241400221210ustar00rootroot00000000000000EXT=mxe flext-0-6-3/buildsys/win/max/gnumake-mingw-flext.inc000066400000000000000000000000511446466241400224500ustar00rootroot00000000000000ifdef SHARED EXT=dll else EXT=LIB endif flext-0-6-3/buildsys/win/max/gnumake-mingw.inc000066400000000000000000000010161446466241400213320ustar00rootroot00000000000000DEFS += -DFLEXT_SYS=1 # fpack-struct should align to 2 bytes... rely on the SDK header files to specify that CFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x501 -DWIN_VERSION -DWIN_EXT_VERSION # suppress multiple symbol errors LDFLAGS += -Wl,--allow-multiple-definition INCPATH += -I$(MAXSDKPATH)/max-includes -I$(MAXSDKPATH)/jit-includes -I$(MAXSDKPATH)/msp-includes LIBPATH += -L$(MAXSDKPATH)/max-includes -L$(MAXSDKPATH)/jit-includes -L$(MAXSDKPATH)/msp-includes # these are both in MAXSDKPATH SYSLIBS += -lMaxAPI -lMaxAudio flext-0-6-3/buildsys/win/max/nmake-msvc-ext.inc000066400000000000000000000000501446466241400214200ustar00rootroot00000000000000EXT=mxe LDFLAGS=$(LDFLAGS) /EXPORT:main flext-0-6-3/buildsys/win/max/nmake-msvc-flext.inc000066400000000000000000000000531446466241400217450ustar00rootroot00000000000000!ifdef SHARED EXT=dll !else EXT=lib !endif flext-0-6-3/buildsys/win/max/nmake-msvc.inc000066400000000000000000000006371446466241400206350ustar00rootroot00000000000000DEFS=$(DEFS) /DFLEXT_SYS=1 CFLAGS=$(CFLAGS) /DWINVER=0x0501 /D_WIN32_WINNT=0x501 /DWIN_VERSION /DWIN_EXT_VERSION INCPATH=$(INCPATH) /I$(MAXSDKPATH)\max-includes /I$(MAXSDKPATH)\jit-includes /I$(MAXSDKPATH)\msp-includes LIBPATH=$(LIBPATH) /LIBPATH:$(MAXSDKPATH)\max-includes /LIBPATH:$(MAXSDKPATH)\jit-includes /LIBPATH:$(MAXSDKPATH)\msp-includes # these are both in MAXSDKPATH LIBS=$(LIBS) maxapi.lib maxaudio.libflext-0-6-3/buildsys/win/nmake-msvc-ext.inc000066400000000000000000000024071446466241400206430ustar00rootroot00000000000000# build class specific settings INCPATH=$(INCPATH) /I$(FLEXTINC) LIBPATH=$(LIBPATH) /LIBPATH:$(FLEXTLIB) LIBS=$(LIBS) $(FLEXTNAME).lib !ifndef SHARED !ifdef SNDOBJ LIBS=$(LIBS) $(SNDOBJ)\lib\SndObj.lib !endif !ifdef STK LIBS=$(LIBS) $(STK)\stk.lib !endif !endif ############################################## # default target _build_: $(TARGET) $(OUTPATH): if not exist $@ mkdir $@ > nul $(TARGETPATH): $(OUTPATH) if not exist $@ mkdir $@ > nul {$(SRCDIR)}.cpp{}.obj: cl /c $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(TARGETPATH)\$@ .cpp.obj: @-mkdir $(TARGETPATH)\$(@D:/=\) 2> NUL cl /c $(CFLAGS) $(DEFS) $(INCPATH) $(SRCDIR)\$** /Fo$(TARGETPATH)\$@ {$(SRCDIR)}.c{}.obj: cl /c $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(TARGETPATH)\$@ .c.obj: @-mkdir $(TARGETPATH)\$(@D:/=\) 2> NUL cl /c $(CFLAGS) $(DEFS) $(INCPATH) $(SRCDIR)\$** /Fo$(TARGETPATH)\$@ $(TARGET):: $(TARGETPATH) $(TARGET):: $(OBJS) @cd $(TARGETPATH) link /DLL $(LDFLAGS) $(LIBPATH) $(OBJS) $(LIBS) /out:$(@F) @cd ..\.. ############################################## # remove build _clean_: -del /q $(TARGETPATH)\*.* > nul -rmdir /q $(TARGETPATH) > nul ############################################## _install_: @if not exist $(INSTPATH) mkdir $(INSTPATH) > nul copy $(TARGET) $(INSTPATH) > nul flext-0-6-3/buildsys/win/nmake-msvc-flext.inc000066400000000000000000000032111446466241400211570ustar00rootroot00000000000000# build class specific settings !ifdef SHARED !ifdef SNDOBJ_LIB LIBS=$(LIBS) $(SNDOBJ_LIB) !endif !ifdef STK_LIB LIBS=$(LIBS) $(STK_LIB) !endif !endif ############################################## # default target _build_: $(TARGET) $(OUTPATH): if not exist $@ mkdir $@ > nul $(TARGETPATH): $(OUTPATH) if not exist $@ mkdir $@ > nul {$(SRCDIR)}.cpp{}.obj: cl /c $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(TARGETPATH)\$@ {$(SRCDIR)}.c{}.obj: cl /c $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(TARGETPATH)\$@ $(TARGET):: $(TARGETPATH) $(TARGET):: $(OBJS) @cd $(TARGETPATH) !ifdef SHARED link /DLL $(LDFLAGS) $(LIBPATH) $(OBJS) $(LIBS) /out:$(@F) !else lib /OUT:$(@F) $(OBJS) !endif @cd ..\.. ############################################## # remove build _clean_: -del /q $(TARGETPATH)\*.* > nul -rmdir /q $(TARGETPATH) > nul ############################################## !ifdef SHARED FLEXTLIBINST=$(FLEXTSHLIB) !else FLEXTLIBINST=$(FLEXTLIB) !endif TMPFILE=$(TARGETPATH)\flext_install_filelist.tmp _install_: # create folders # -@if not exist $(FLEXTINC) mkdir $(FLEXTINC) > nul -@if not exist $(FLEXTLIB) mkdir $(FLEXTLIB) > nul -@if not exist $(FLEXTLIBINST) mkdir $(FLEXTLIBINST) > nul -copy $(TARGET) $(FLEXTLIBINST) > nul !ifdef SHARED # copy import library -copy $(TARGET:.dll=.lib) $(FLEXTLIB) > nul !endif # copy headers (probably with subpath) -@del $(TMPFILE) 2>nul -@for %%i in ($(HDRS)) do @echo %%i >> $(TMPFILE) -@for /f "tokens=1,2 delims=/" %%i in ($(TMPFILE)) do @if "%%j" == "" ( copy $(SRCDIR)\%%i $(FLEXTINC) > nul ) else ( mkdir $(FLEXTINC)\%%i 2>nul & copy $(SRCDIR)\%%i\%%j $(FLEXTINC)\%%i > nul ) -@del $(TMPFILE) 2>nul flext-0-6-3/buildsys/win/nmake-msvc-shlib.inc000066400000000000000000000017321446466241400211440ustar00rootroot00000000000000# build class specific settings INCPATH=$(INCPATH) /I$(FLEXTINC) LIBPATH=$(LIBPATH) /LIBPATH:$(FLEXTLIB) LIBS=$(LIBS) $(FLEXTNAME).lib ############################################## # default target _build_: $(TARGET) $(OUTPATH): if not exist $@ mkdir $@ > nul $(TARGETPATH): $(OUTPATH) if not exist $@ mkdir $@ > nul {$(SRCDIR)}.cpp{}.obj: cl /c $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(TARGETPATH)\$@ {$(SRCDIR)}.c{}.obj: cl /c $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(TARGETPATH)\$@ $(TARGET):: $(TARGETPATH) $(TARGET):: $(OBJS) @cd $(TARGETPATH) link /DLL $(LDFLAGS) $(LIBPATH) $(OBJS) $(LIBS) /OUT:$(@F) @cd ..\.. ############################################## # remove build _clean_: -del /q $(TARGETPATH)\*.* > nul -rmdir /q $(TARGETPATH) > nul ############################################## _install_: @if not exist $(FLEXTSHLIB) mkdir $(FLEXTSHLIB) > nul copy $(TARGET) $(FLEXTSHLIB) > nul # copy import library copy $(TARGET:.dll=.lib) $(FLEXTSHLIB) > nul flext-0-6-3/buildsys/win/nmake-msvc.inc000066400000000000000000000030471446466241400200460ustar00rootroot00000000000000!ifdef MSVCPATH INCPATH=$(INCPATH) /I$(MSVCPATH)\include LIBPATH=$(LIBPATH) /LIBPATH:$(MSVCPATH)\lib !endif !ifdef LOCKFREEPATH INCPATH=$(INCPATH) /I$(LOCKFREEPATH) !endif !ifdef SNDOBJ_INC INCPATH=$(INCPATH) /I$(SNDOBJ_INC) !endif !ifdef STK_INC INCPATH=$(INCPATH) /I$(STK_INC) !endif ############################################## OBJPATH=$(OUTPATH)\$(OUTSUB) TARGETPATH=$(OBJPATH) TARGET=$(TARGETPATH)\$(OUTNAME).$(EXT) ############################################## # use precompiled headers (automatic mode) !ifdef PRECOMPILE CFLAGS=$(CFLAGS) /YX$(PRECOMPILE) /Fp$(OBJPATH)\precompiled.pch !endif ############################################## # create code for DLL CFLAGS=$(CFLAGS) /LD # enable exception handling, RTTI and intrinsic functions CFLAGS=$(CFLAGS) /EHsc /GR /Oi # no banner CFLAGS=$(CFLAGS) /nologo LDFLAGS=$(LDFLAGS) /nologo # inhibit VC8 warnings CFLAGS=$(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE # default Windows flags as defined from VC IDE CFLAGS=$(CFLAGS) /DWIN32 /D_WINDOWS ############################################## !ifdef DEBUG !ifdef DYNAMIC CFLAGS=$(CFLAGS) /MDd LIBS=$(LIBS) MSVCPRTD.LIB MSVCRTD.LIB !else CFLAGS=$(CFLAGS) /MTd LIBS=$(LIBS) LIBCPMTD.LIB LIBCMTD.LIB !endif LDFLAGS=$(LDFLAGS) /DEBUG !else !ifdef DYNAMIC CFLAGS=$(CFLAGS) /MD LIBS=$(LIBS) MSVCPRT.LIB MSVCRT.LIB !else CFLAGS=$(CFLAGS) /MT LIBS=$(LIBS) LIBCPMT.LIB LIBCMT.LIB !endif LDFLAGS=$(LDFLAGS) /INCREMENTAL:NO !endif ############################################## # convert both *.c and *.cpp OBJSTMP= $(SRCS:.c=.obj) OBJS= $(OBJSTMP:.objpp=.obj) flext-0-6-3/buildsys/win/pd/000077500000000000000000000000001446466241400157115ustar00rootroot00000000000000flext-0-6-3/buildsys/win/pd/config-cygwin.def000066400000000000000000000020251446466241400211330ustar00rootroot00000000000000# where is the PD installation? # (this should point to the main folder, which has a "src" (PD Vanilla) or "include" (PD extended) subfolder) PDPATH=/cygdrive/c/program files/pd ############################################################### # where do/should the flext headers reside/be built? FLEXTINC=$(PDPATH)/flext # where do/should the flext static libraries reside/be built? FLEXTLIB=$(FLEXTINC) # where do/should the flext shared libraries reside/be built? FLEXTSHLIB=$(PDPATH)/bin ############################################################### # where should the external be built? OUTPATH=pd-cygwin # where should the external be installed? INSTPATH=$(PDPATH)/extra ############################################################### # make flags (e.g. use multiprocessor) #MFLAGS=-j 2 # user defined compiler flags # (check if they match your system!) UFLAGS=-msse -mfpmath=sse -ffast-math # user defined optimization flags # (check if they match your system!) OFLAGS=-O3 # optimizations for Pentium 4 OFLAGS+=-march=pentium4 flext-0-6-3/buildsys/win/pd/config-gcc.def000066400000000000000000000040311446466241400203660ustar00rootroot00000000000000# where is the PD installation including source code? # (this should point to the main folder, which has a "src" (PD Vanilla) or "include" (PD extended) subfolder) PDPATH=/Applications/Pd-0.40-2.app/Contents/Resources # where is the PD executable? PDBIN=$(PDPATH)/bin/pd ############################################################### # prefix for flext installation # headers are in $(FLEXTPREFIX)/include/flext # libraries are in $(FLEXTPREFIX)/lib # build system is in $(FLEXTPREFIX)/lib/flext FLEXTPREFIX=/usr/local ############################################################### # where should the external be built? OUTPATH=pd-gcc # where should the external be installed? INSTPATH=$(PDPATH)/extra ############################################################### # STK (synthesis tool kit) support # http://ccrma.stanford.edu/software/stk # where to find the STK header files (e.g. stk.h) STK_INC=/usr/local/include/stk # where to find the STK library (normally libstk.a) # (comment out STK_LIB if you don't use STK) #STK_LIB=/usr/local/lib/libstk.a ############################################################### # SndObj support # http://music.nuim.ie//musictec/SndObj # where to find the SndObj header files (e.g. sndobj.h) SNDOBJ_INC=/usr/local/include/sndobj # where to find the SndObj library (normally libsndobj.a) # (comment out STK_LIB if you don't use SndObj) #SNDOBJ_LIB=/usr/local/lib/libsndobj.a ############################################################### # make flags (e.g. use multiprocessor) #MFLAGS=-j 2 # user defined compiler flags UFLAGS += -ffast-math # user defined optimization flags OFLAGS += -Os -ftree-vectorize # user defined debugging flags DFLAGS += # architecture-specific flags (optional) UFLAGS_ppc += -maltivec -faltivec OFLAGS_ppc += -mtune=G4 DFLAGS_ppc += UFLAGS_i386 += -mmmx -msse -msse2 -msse3 OFLAGS_i386 += -mtune=prescott DFLAGS_i386 += # cross-compilation (optional) #ARCH=i386 ppc #OSXSDK=/Developer/SDKs/MacOSX10.4u.sdk flext-0-6-3/buildsys/win/pd/config-mingw.def000066400000000000000000000026551446466241400207650ustar00rootroot00000000000000# where is the PD installation? # (this should point to the main folder, which has a "src" (PD Vanilla) or "include" (PD extended) subfolder) PDPATH="%ProgramFiles%\pd" ############################################################### # version of the pthreads library (the one coming with PD has version number 1) PTHREADSVERSION=1 # path to pthreads headers (PD comes with some in the src folder) PTHREADSINC=$(PDPATH)\src # path to pthreads link library (PD comes with one in the bin folder) PTHREADSLIB=$(PDPATH)\bin ############################################################### # where do/should the flext headers reside/be built? FLEXTINC=$(PDPATH)\flext # where do/should the flext static libraries reside/be built? FLEXTLIB=$(FLEXTINC) # where do/should the flext shared libraries reside/be built? FLEXTSHLIB=$(PDPATH)\bin ############################################################### # where should the external be built? OUTPATH=pd-mingw # where should the external be installed? INSTPATH=$(PDPATH)\extra ############################################################### # make flags (e.g. use multiprocessor) #MFLAGS=-j 2 # user defined compiler flags # (check if they match your system!) UFLAGS=-msse -mfpmath=sse -ffast-math # user defined optimization flags # (check if they match your system!) OFLAGS=-O3 # optimizations for Pentium 4 OFLAGS+=-march=pentium4 # comment if you want to compile for Windows 95/98/ME WINNT=1 flext-0-6-3/buildsys/win/pd/config-msvc.def000066400000000000000000000064521446466241400206130ustar00rootroot00000000000000# where is the PD installation? # (this should point to the main folder, which has a "src" (PD Vanilla) or "include" (PD extended) subfolder) PDPATH="%ProgramFiles%\pd" # where is MS VC++? # (not necessary if the build is run with the compiler environment) # MSVCPATH="%ProgramFiles%\Microsoft Visual Studio .NET 2003\Vc7" ############################################################### # version of the pthreads library (the one coming with PD has version number 1) PTHREADSVERSION=1 # path to pthreads headers (PD comes with some in the src folder) PTHREADSINC=$(PDPATH)\src # path to pthreads link library (PD comes with one in the bin folder) PTHREADSLIB=$(PDPATH)\bin ############################################################### # path to lockfree library LOCKFREEPATH=$(FLEXTINC)\source\lockfree ############################################################### # where do/should the flext headers reside/be built? FLEXTINC=$(PDPATH)\flext # where do/should the flext static libraries reside/be built? FLEXTLIB=$(FLEXTINC) # where do/should the flext shared libraries reside/be built? FLEXTSHLIB=$(PDPATH)\bin ############################################################### # where should the external be built? # (relative one-level subpath to project folder) OUTPATH=pd-msvc # where should externals be installed? INSTPATH=$(PDPATH)\extra ############################################################### # where is the STK installation? # (uncomment the line with # to disable STK support) # -------------------------------------------------------------------- # In order to use STK you must have an stk.lib library # Using MSVC you can build it as following (from the STK main folder): # cl /c /GR /EHsc /Iinclude /MT /Ox src\*.cpp # (in case you define DYNAMIC=1 below, omit the /MT flag and set /MD instead) # (you will get errors for some files, you can ignore them in the flext context) # lib *.obj /out:stk.lib # # where to find the STK header files (e.g. stk.h) #STK_INC=%HOMEDRIVE%\%HOMEPATH%\stk\include # where to find the STK library (normally stk.lib) # (comment out STK_LIB if you don't use STK) #STK_LIB=%HOMEDRIVE%\%HOMEPATH%\stk\stk.lib # where is the Sndobjs installation? # (uncomment the line with # to disable SNDOBJ support) # -------------------------------------------------------------------- # Please be sure to delete an eventual m_pd.h file from the SNDOBJ include folder!! # The shared flext library links to the SndObj.lib file from the SNDOBJ distribution. # Flext must be compiled with the same compiler version as the SNDOBJ lib (default MSVC6) # # where to find the SndObj header files (e.g. SndObj.h) #SNDOBJ_INC=%HOMEDRIVE%\%HOMEPATH%\SndObj\include # where to find the SndObj library (normally SndObj.lib) # (comment out SNDOBJ_LIB if you don't use SndObj) #SNDOBJ_LIB=%HOMEDRIVE%\%HOMEPATH%\SndObj\lib\SndObj.lib ############################################################### # user defined compiler flags # (check if they match your system!) UFLAGS= # user defined optimization flags # (check if they match your system!) OFLAGS=/Ox # optimizations for Pentium 4 OFLAGS=$(OFLAGS) /G6 /arch:SSE # comment if you want to compile for Windows 95/98/ME WINNT=1 # uncomment to link against dynamic C runtime libraries # (don't use this if you want to distribute the built product) #DYNAMIC=1 flext-0-6-3/buildsys/win/pd/gnumake-cygwin-ext.inc000066400000000000000000000000101446466241400221160ustar00rootroot00000000000000EXT=dll flext-0-6-3/buildsys/win/pd/gnumake-cygwin-flext.inc000066400000000000000000000000461446466241400224510ustar00rootroot00000000000000ifdef SHARED EXT=dll else EXT=a endif flext-0-6-3/buildsys/win/pd/gnumake-cygwin-shlib.inc000066400000000000000000000000101446466241400224170ustar00rootroot00000000000000EXT=dll flext-0-6-3/buildsys/win/pd/gnumake-cygwin.inc000066400000000000000000000003721446466241400213330ustar00rootroot00000000000000DEFS += -DFLEXT_SYS=2 -DPD INCPATH += -I$(PDPATH)/src -I$(PDPATH)/include -I$(PDPATH)/include/pd THR=0 ifdef THREADED THR=1 endif ifdef SHARED THR=1 endif ifeq ($(THR),1) LIBS += $(PDPATH)/bin/pthreadVC.dll endif SYSLIBS += $(PDPATH)/bin/pd.dll flext-0-6-3/buildsys/win/pd/gnumake-gcc-ext.inc000066400000000000000000000001331446466241400213600ustar00rootroot00000000000000EXT=dll LDFLAGS += -shared TARGET=$(TARGETPATH)/$(TARGETNAME) INSTTARGET=$(TARGET) flext-0-6-3/buildsys/win/pd/gnumake-gcc-flext.inc000066400000000000000000000002771446466241400217130ustar00rootroot00000000000000ifdef SHARED EXT=dll else EXT=a endif LDFLAGS += -shared VERNAME=$(OUTNAME).$(FLEXTMAJOR).$(FLEXTMINOR).$(FLEXTMICRO).$(EXT) TARGET=$(TARGETPATH)/$(VERNAME) INSTTARGET=$(TARGET) flext-0-6-3/buildsys/win/pd/gnumake-gcc.inc000066400000000000000000000013611446466241400205660ustar00rootroot00000000000000DEFS += -DFLEXT_SYS=2 -DPD ifdef WINNT DEFS += -D_WIN32_WINNT=0x500 endif ############################################## # let the pthreads path be first, because pthreads headers could also be a $(PDPATH)/src INCPATH += -I$(PTHREADSINC) THR=0 ifdef THREADED THR=1 endif ifdef SHARED THR=1 endif ifeq ($(THR),1) ifeq ($(PTHREADSVERSION),2) LIBS += $(PTHREADSLIB)/pthreadVC2.dll else LIBS += $(PTHREADSLIB)/pthreadVC.dll endif endif ############################################## INCPATH += -I$(PDPATH)/src -I$(PDPATH)/include -I$(PDPATH)/include/pd ############################################## OBJPATH=$(OUTPATH)/$(OUTSUB) TARGETPATH=$(OBJPATH) TARGETNAME=$(OUTNAME).$(EXT) LIBS += $(PDPATH)/bin/pd.dll flext-0-6-3/buildsys/win/pd/gnumake-mingw-ext.inc000066400000000000000000000000101446466241400217370ustar00rootroot00000000000000EXT=dll flext-0-6-3/buildsys/win/pd/gnumake-mingw-flext.inc000066400000000000000000000000461446466241400222720ustar00rootroot00000000000000ifdef SHARED EXT=dll else EXT=a endif flext-0-6-3/buildsys/win/pd/gnumake-mingw-shlib.inc000066400000000000000000000000101446466241400222400ustar00rootroot00000000000000EXT=dll flext-0-6-3/buildsys/win/pd/gnumake-mingw.inc000066400000000000000000000010271446466241400211520ustar00rootroot00000000000000DEFS += -DFLEXT_SYS=2 -DPD ifdef WINNT CFLAGS += -D_WIN32_WINNT=0x500 endif ############################################## # let the pthreads path be first, because pthreads headers could also be a $(PDPATH)/src INCPATH += -I$(PTHREADSINC) LIBPATH += -L$(PTHREADSLIB) ifdef THREADED ifeq ($(PTHREADSVERSION),2) LIBS += -lpthreadVC2 else LIBS += -lpthreadVC endif endif ############################################## INCPATH += -I$(PDPATH)/src -I$(PDPATH)/include -I$(PDPATH)/include/pd LIBPATH += -L$(PDPATH)/bin LIBS += -lpd flext-0-6-3/buildsys/win/pd/nmake-msvc-ext.inc000066400000000000000000000000101446466241400212320ustar00rootroot00000000000000EXT=dll flext-0-6-3/buildsys/win/pd/nmake-msvc-flext.inc000066400000000000000000000000531446466241400215630ustar00rootroot00000000000000!ifdef SHARED EXT=dll !else EXT=lib !endif flext-0-6-3/buildsys/win/pd/nmake-msvc-shlib.inc000066400000000000000000000000101446466241400215330ustar00rootroot00000000000000EXT=dll flext-0-6-3/buildsys/win/pd/nmake-msvc.inc000066400000000000000000000011771446466241400204530ustar00rootroot00000000000000DEFS=$(DEFS) /DFLEXT_SYS=2 /DPD !ifdef WINNT DEFS=$(DEFS) /D_WIN32_WINNT=0x500 !endif ############################################## # let the pthreads path be first, because pthreads headers could also be a $(PDPATH)/src INCPATH=$(INCPATH) /I$(PTHREADSINC) LIBPATH=$(LIBPATH) /LIBPATH:$(PTHREADSLIB) !if defined(THREADED) | defined(SHARED) !if $(PTHREADSVERSION) == 2 LIBS=$(LIBS) pthreadVC2.lib !else LIBS=$(LIBS) pthreadVC.lib !endif !endif ############################################## INCPATH=$(INCPATH) /I$(PDPATH)\src /I$(PDPATH)\include /I$(PDPATH)\include\pd LIBPATH=$(LIBPATH) /LIBPATH:$(PDPATH)\bin LIBS=$(LIBS) pd.lib flext-0-6-3/changes.txt000066400000000000000000000517361446466241400150400ustar00rootroot00000000000000flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001-2023 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ---------------------------------------------------------------------------- Version history: 0.6.3: - Added support of pd64 (double precision samples for Pure data) 0.6.2: - Got rid of unmaintained compilers and IDEs (Borland C, icc, Metrowerks) and platforms (OS 9, IRIS, jmax) 0.6.1: - flext supports 64-bit DSP in Pure Data (and presumable also Max) 0.6.0: - FLEXT_INLINE allows use of without further libraries 0.5.2: - 64-bit arch fixes (Pd 0.42) - STK API adaptations 0.5.1: - optimizations for message handling and memory footprint - enhanced build system for cygwin - added GetCanvasDir to retrieve folder in which the patcher resides - better handling of click callback - more compatible handling of attributes in patcher (hiding is now an option - define FLEXT_ATTRHIDE) - added header file flfeatures.h for compile-time detection of version-specific features - typed flext::NewAligned allocator - fixed severe Altivec bug (load unaligned)... thanks to Ian Ollmann - restructured initialization and finalization (esp. Max DSP stuff) - real class names now also reflect debug mode (like in flext_base_shared_d) - cleaned up internals (like Max/MSP typedefs) - fixed coexistence of message and signal objects in Max/MSP object libraries - fixes for pthreads version 2 - deprecated FLEXT_NOGLOBALNEW in favor of FLEXT_USE_CMEM (either global new/delete operators or C library memory allocation) - fixing uninitialized pointer (first inlet pointer) - added message bundle functionality (to send more messages over the thread boundary to arrive at the same logical time) - fixed dangerous spot (also memory leak) with message queuing - fixed buggy freeing of memory for AtomListStatic - optimizations around method registration - preprocessor symbol FLEXT_COMPATIBLE - if defined don't implement specialities of either Pd or Max/MSP - Max: fixed reported bug (#67), where list elements are distributed over inlets - added thisParent type, which refers to the class from which the current flext class is derived (as given in FLEXT_HEADER) - bang method can also by added with FLEXT_(C)ADDMETHOD (FLEXT_(C)ADDBANG is still an alias) - attribute generation is now determined exclusively by each object class setup (not library is before) - more robust pack setting for Max/MSP @ Windows - should work with Mac/Intel (still untested!) - added new FLEXT_HEADER macros to enable class templates - more ToOut/Sys* methods - fixed help name definition at class setup - added gcc branch hinting - Pd: possibility to create DSP classes without main DSP inlet (use e.g. FLEXT_DSP0_NEW) - fixed atom sorting (symbols were sorted by pointer, not by content) - updated build system to handle UB on OSX (including architecture-specific compiler flags) - new idle callback/method functionality - Max: fixed bug at destructing of proxy objects - fixed message processing of empty lists - fixed STK inlet processing 0.5.0: - fixes for 64 bit builds (size_t is integer type of pointer size) - finally added a autoconf system (many many thanks to Tim Blechmann) - more character escapes for attribute editor - fixed the attribute editor for 0.38, stopped redundant transfer of script code - show saveable attributes on object select - fix for long attribute dialogs - dropped support for Max UI objects - added global system locking - added general atom outlet functions To{Sys,Out,Queue}Atom - new build system for flext and flext-based externals - flags for object construction and destruction phase (Initing() and Exiting()) - reconsidered flext::buffer::Update - enhanced buffer handling - support for buffer locking (flext::buffer::Lock() and Unlock()) - it's a must for Max/MSP at least - use new Pd idle callback for queues messages (currently in devel_0_38) - fixed bug with unregistering for bound symbols - removed virtual m_assist function (which was only useful for Max)... stick to static assist strings - removed virtual flext_dsp::m_enable function (which wasn't present for Max/MSP) - added m_click method which gets called on alt-click (Pd) resp. double clicks (Max) onto the object box - in ToOut check if we are inside dsp (and use ToQueue then...) - some restructuring and use symbols (rather than char *) natively for AddMethod* and AddAttrib* functions - added some more SIMD functionality - fixes to flext::Timer::At method - eliminated misleading flext_dsp::ChannelsIn and ChannelsOut - added lock-free Lifo and Fifo structures and used it with message queueing and thread management - eliminated default "help" (m_help) method... should be implemented in the flext-based object - changed virtual callback names m_loadbang, m_method_, m_dsp, m_signal, m_click to CbLoadbang, CbMethodResort, CbDsp, CbSignal, CbClick - replaced memory-intensive STL maps by custom-made vector/map-monster (should be fast!) - fixed bug for symbol messages into non-left inlets - better timers for Windows - slimmed down object data structures and changed initialization code accordingly - digest one-element float/int/symbol/pointer list messages as single atoms - simplified message analysis - made flext::Forward thread safe 0.4.7: - added flext::GetBool (just because flext::GetInt has been there for a while) - added bool to usable types for creation arguments - protection for SIMD routines with count=0 - support exceptions for setup functions, object creation and destruction, method handling - small fixes for MSVC6 incompatibilites - fixes for Max 4.5 headers - removed Mach-O/CFM glue stuff again and added makefiles for Max/MachO - in flext::StopThread don't wait for thread to have stopped! - support Pd tooltips (only in devel branch at the moment) - attribute editor: added individual apply buttons - attribute editor: added escaping for , and ; - attribute editor: zoomed editor accepts , as newline separator - attribute editor: close editor window on object destruction - fixed $0-arguments in attribute saving - introducing ring buffer for message queue (thanks to Tom Schouten) - printing of atoms into buffer with better error checking 0.4.6: - added a text edit window for list attributes - finally use global allocator operators (MFC doesn't like it but who cares) - fixed entry of local variables with attribute editor - help window for attribute editor - appended lacking ~ for tilde object help patches - uniform STL container for all kinds of attribute, method, class handling - support for MinGW - added flext_obj::CanvasArgs - fixed small problem with buffer->Valid() on startup - fixed buffer overrun problems with flext::post, flext::error... (but still to improve) - improved handling of patcher arguments - also initialize flext::sym_int as MakeSymbol("int") for Pd (since the variable is there anyhow) - fixed bug with attribute dumping - default arguments for object construction (types float0,int0,t_symtype0 for FLEXT_NEW*) - added flext::sym__ for empty symbol "" 0.4.5: - added some more SIMD functions - Pd attributes: added a TCL/TK editor dialog ("properties") and save attributes to patcher - fixed wrong returned result of flext::buffer::set function - fix for linux static exported function name-clash (individual linker namings for exported flext base classes) - made message queue stuff global (static) for all flext objects - added flext_base::DumpAttrib to send an attribute value to the attribute outlet - added "getmethods" message (for attribute-enabled externals) to list methods for a specified inlet (default = 0) - "getattributes" or "getmethods" output lists are now alphabethically sorted - flext::StopThread function to terminate running threads (started with LaunchThread) - added flext::CmpAtom and AtomList::operator < methods ... useful for using lists as keys for STL - make use of new Pd thread locking (Pd functions sys_lock() and sys_unlock()), queue messages only if necessary - better FLEXT_OSAPI resolution - ListAttributes (or the getattributes message) now lists attributes in the order they were created (first class, then object scope) - enforcing usage of STL - explicit boolean attributes (great for attribute editor layout!) - flext_dsp reported wrong inlet/outlet count (CntInSig, CntOutSig functions) - added support for patcher arguments for attributes (use # instead of $ to save them with a patch) - moved memory functions and console output from flext to super-base-class flext_root and derived all helper classes from that - changed FLEXT_THREAD_X: wrappers doesn't delete the passed data pointer anymore -> the called method is responsible for that (and it knows the type....) - enabled binding of more than one function to a symbol and added flext_base::GetBoundMethod - native support for Windows threading model 0.4.4: - fixed deadly bug for Max/MSP method-to-symbol-binding proxies - some fixes for CodeWarrior Mach-O compilation - fixed destruction bug for hashed "item arrays" - added flext_base::ToSelf* methods for queued (deferred) self messaging - deleted flext::buffer console outputs for undefined arrays/buffer~s: should be done by externals - a few changes for the flext shared library - tiny update for Pd 0.37 header file usage - fixed a bug associated to attribute argument lists - added functions for version number and string (flext::Version and flext::VerStr, mainly for usage of a shared flext library) - flext_base::UnbindMethod returns user data - fixed compilation problem with t_symbol-type attributes - added methods for sending boolean values (ToOutBool, ToQueueBool, ToSelfBool) 0.4.3: - added forgotten flext_base::ToQueueString method - added timer functions and flext::Timer class - added functions for SIMD support - fixed race condition when using LaunchThread in a setup function (now waiting for thread helper to initialize) - added flext::Forward function to send messages to bound symbols - added "zero" flag to flext::buffer resize operation - fixed bug for Max/MSP buffer resize with preservation of contents - fixed bug with thread initialization (caused Pd@OSX to crash on startup) - flext::setup is only run once now - fixed creation bug with objects that have attributes but no outlets - added FLEXT_BINDMETHOD,FLEXT_UNBINDMETHOD to bind a method to a symbol - fixed bug with hard thread termination (of incooperative threads) 0.4.2: - started port for jMax - moved CLASS_MAINSIGNALIN to class scope (fixed "float method overwritten" warning) - unix makefiles: CXX should be commented out if standard (to enable environmental settings) - introduced default returns for the different flext::GetA* functions - pragma for Metrowerks compilers: enumsalwaysint on, bool on - MaxMSP: added assist string for attribute outlets - added new POSIX for ThrCond::TimedWait (but still have to find out when to enable it....) - added CopySamples and ZeroSamples - fixed bug for DSP object with zero signal inlets in Pd - added validity check for sample buffers 0.4.1: - full port for Max@OSX - completely redesigned message and attribute handling: now hashed and much more efficient - greatly enhanced object creation and destruction (esp. for library objects) - class setup functions now take t_classid type arg... this is BACKWARDS-INCOMPATIBLE for Max/MSP - added some prerequisites for usage of flext as a shared library - completed Max/MSPs inlet/outlet assist description functionality - Max/MSP signal objects: fixed bug of reporting wrong number of inlets - put overloaded new/delete into flext support class - introduced "Finalize" virtual method, called after all "Init" methods - fixed crash issue in flext_dsp when there are NO signal inlets or outlets defined (this is possibly only a problem for the signal2 tutorial example) - added flext::GetType(t_atom &), flext::ZeroMem - put the clock_delay for the message queue inside the thread-locked area Ok for the actual object, but Pd has to be thread-safe here as well - BACKWARDS-INCOMPATIBLE CHANGE: flext_base::m_methodmain and flext_base::m_method_ have got const modifiers.... these virtual methods are used rarely (except for example in py/pyext) - now MUCH cleaner platform identification... FLEXT_SYS,FLEXT_OS,FLEXT_CPU definitions - also FLEXT_DEBUG for debug build - SndObjs: virtual FreeObject routine is now called at destruction (by parent class), derived class doesn't need to call it! - SndObjs: fixed typo (numbers of output slots was wrong) and init bug - STK: added support for STK object classes (flstk.{h,cpp}) - introduced a helper thread for launching flext threads in the background - threads are now handled on class (as opposed to object) level - threads can now be terminated separately - put more flext functions into flext static class - replaced ChangePriority by RefPriority - fixed setting of priorities... problems were caused by a compiler bug (MSVC 6) - made a portable threading interface with support for threading libraries other than pthreads (FLEXT_THREADS defined as FLEXT_THR_*) - implemented threading support with the MacOS MP thread library - stripped the ThrMutex and ThrCond classes of non-portable (and irrelevant) functionality - simplified "ToQueue*" and threaded "ToOut*" message queue mechanism for Max/MSP - deprecated FLEXT_ADDMETHOD_V and FLEXT_ADDMETHOD_A definitions which only lead to confusion - BACKWARDS-INCOMPATIBLE CHANGE: flext_sndobj::NewObjs must return a boolean!! 0.4.0: - the use of the const keyword is enforced (e.g. the preferred type for symbols is now "const t_symbol *") - there _might_ be some problems with sensitive compilers - introduced Max/Jitter-like attribute functionality ("@value" command line, "getvalue" get and "value" set functions) - introduced a flext static class for general flext functions (to clean up the flext_base class) - creation argument handling is now done by flext no more weird Pd re-ordering of arguments - no more support for the Apple MPW compiler - MacOS9 is dying anyway... - calling SetupInOut() has become obsolete - flext creates all inlets/outlets by itself after the constructor has finished - this implies that CntIn(),CntOut() and the outlet pointers are not valid in the constructor - there is a virtual bool Init() function that may be used for such initialization - completely redesigned FLEXT_NEW macros, usage of dynamic classes (in fllib.cpp) - added ToQueue* functions - like ToOut* but messages or not directly sent (well suited for deadlock situations) - introduced additional per-class methods and attributes (just like it ever was in Max and Pd) - fixed potentially dangerous typo in flext.cpp - (was: FLEXT_THREAD instead of FLEXT_THREADS) - added OSX/darwin support (originally done by Adam T. Lindsay) - SndObj interface now also available for cygwin and BCC - added prepend and append functions to AtomList class - added IsNothing, SetNothing, CanbeBool and GetABool functions - eliminated the remaining Get*Flint and Set*Flint functions - added/completed Is/Canbe/Get/Set for pointer atoms - added print/scan functions for atoms - fixed anything outlets for Max/MSP... for some strange reason this severe bug has not had severe consequences.... 0.3.3: - Pd: fixed bug for DSP objects having no signal inlets this also enables floats into a non-signal leftmost inlet - revisited priority stuff for detached threads - Bind/unbind functions for flext classes (in MaxMSP only one object can be bound) - made "t_symtype" another synonym for "t_symbol *" - added forgotten dsp_free function for MaxMSP - fixed forgotten __class__ member for MaxMSP libraries - changed basic MaxMSP object to t_pxbox (ok, a bit more memory is used....) - MaxMSP library can now be loaded from startup folder (but can't use aliases) - if no handler is found for pure anything (just symbol, no args...) try list handler - added interface for SndObj (http://www.may.ie/academic/music/musictec/SndObj/ ) 0.3.2: - Doxygen generated inline documentation / functional reference - added some more functionality to the AtomAnything class - bugfix for threaded methods with var list or anything arguments - added threaded method for arbitrary (void *) data structs - ThrMutex: added lock count functions Push() and Pop() - eliminated potentially dangerous SetThing,GetThing and introduced DoBind,DoUnbind,GetBound instead - fixed severe bug with the current threads list - add path specification possibility for help symbols (in FLEXT_NEW*) - use pthread_attr and DETACHED flag 0.3.1: - added some more functionality to the AtomList class - fixed forgotten Sleep implementation in pd@unix - reorganized file structure and config/make procedures 0.3.0: - added CYGWIN support - added threaded methods along with a message queue for ToOut* functions (very unstable for MaxMSP!) to use threads compile flext with FLEXT_THREADS definition - check/update function for buffer change (resize etc.) - description text for inlets/outlets (e.g. for MaxMSPs assist function) - not fully implemented - added buffer resize functions flext_base::buffer::Frames(int,bool) - added some utility functions: Sleep, CopyAtom, CopyList - added List manipulation classes: AtomList, AtomAnything - Alias object names (simply specify with FLEXT_NEW*, separated by whitespace) - float messages - int method is called if there is no float method - MaxMSP: int messages - float method is called if there is no int method - fixed type warning for class constructors with int arguments in Pd - fixed severe bug concerning symbol methods - MaxMSP: use critical sections for message output (for more safety in overdrive mode) - Pd: default/manual definition of help file by flext_base::DefineHelp - added GetThing/SetThing to access t_symbol's s_thing data member - introduced FLEXT_NEW_DSP* and FLEXT_LIB_DSP* for FLEXT_NEW_TILDE* and FLEXT_LIB_TILDE* (the latter become deprecated) - all variable argument defs (aka gimme) now have a V instead of G (e.g. FLEXT_NEW_V) 0.2.3: - restructured files and started usable inline documentation - found that there was no method to output a bang?! Ugh! -> corrected - finally eliminated awful t_flint type and all other schizophrenic flint functions (float and int exist now equally) - now (finally) using type t_sample for sample values (should just be identical to float) - added AddInBang/AddOutBang (same as Add*Symbol - unchecked) - buffer class: added "bool Ok()" check function - switched on error posting for unhandled messages - added XletCode and AddInlets/AddOutlets for multiple Inlet/Outlet addition (max. 9 inlets/outlets) - if float or int message is not handled explicitly then [list float/int( is tried 0.2.2: - added xgimme argument type (supplies method handlers with symbol+gimme) - more information on DSP system with flext_dsp object (block size,number of audio inputs and outputs) - cleaner gcc makefile - made NewAligned/FreeAligned static functions - introduced FLEXT(_TILDE)_SETUP for class setup in a library setup function - introduced external libraries for MaxMSP, changed library setup behavior (now via FLEXT_LIB_SETUP) - included MaxMsp's inofficial buffer.h with consent by David Zicarelli - changed dynamic casts in callback functions to static as gcc 3.0.4 has obvious bugs 0.2.1: - fixed bug in message parsing code (anything messages were not correctly mapped to inlets) - changed t_symtype to t_symptr (= t_symbol *), needed for method argument lists - eliminated flint type (t_flint remains) 0.2.0: - internal proxy objects for any non-leftmost inlets - Max/MSP: all signal inlets can receive messages - method/argument parsing is done by flext - float/int are not distinguished, the first handler wins - integrated more system functions into flext_base & eliminated superfluous #defines - distribute list (into inlet 0) elements over inlets (right to left) - added outlets for anythings - defines for callback-to-method functions and method setup (FLEXT_CALLBACK*, FLEXT_ADD*) - uses Pd's or Max's memory allocation functions (for safety in Max's overdrive) - no support for default arguments (A_DEFFLOAT and A_DEFSYMBOL).. use GIMME instead! - better graphics update behavior for Pd - improved behavior for invalid/undefined buffers/arrays - use MaxMSP internal z_disabled flag with flext_dsp for pausing/resuming dsp processing - included CHECK_TILDE, a test whether a tilde object (defined as FLEXT_TILDE_*) has a trailing ~. (debug mode only) - changed notation of flext functions from to_out_float like to ToOutFloat like - eliminated trivial shortcuts (F,I,V,...) for built-in types - MaxMSP is only capable of 3 creation arguments... that should be sufficient - otherwise use GIMME - Methods for aligned memory (NewAligned, FreeAligned) 0.1.1: - documentation for flext.h - more emancipation from GEM code - virtually everything renamed - abstraction for dsp processing - makefile for BCC - manual call of extern_setup or main unnecessary for single objects - only in pd libraries - delayed buffer init (only name is set beforehand) - loadbang also in Pd - introduced "compatibility mode" which denies platform-specific features - fixed severe dsp bug (symptom: "float method overwritten" warning in pd) - fixed bug: wrong return code from buffer::Set 0.1.0: - max-pd 0.2 becomes flext 0.1.0 - heavy usage of unchanged GEM code flext-0-6-3/configure.ac000066400000000000000000000175131446466241400151500ustar00rootroot00000000000000# # autoconf template # modified by Thomas Grill # # flext API version (current:release:age) # API_VERSION=0:0:0 AC_INIT([flext],[0.6.3],[gr@grrrr.org]) AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_MACRO_DIRS([m4]) AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl ' FLEXT_EXT_CFLAGS="" AC_CANONICAL_HOST AC_LANG(C++) AS_CASE([$host], [*mingw*|*cygwin*], [win=1], [win=""]) # configure options AC_ARG_ENABLE(system, AS_HELP_STRING([--enable-system],[realtime system [default=pd]]), [SYSTEM=$enableval], [SYSTEM=pd] ) AC_ARG_WITH(sdkdir, AS_HELP_STRING([--with-sdkdir],[path to pd or max headers]), [sdkdir=$withval], AC_MSG_ERROR(path to system SDK headers required $withval) ) AC_ARG_WITH(externalsdir, AS_HELP_STRING([--with-externalsdir],[path to install externals to]), [EXTDIR="${withval}"]) AC_ARG_WITH(pdbindir, AS_HELP_STRING([--with-pdbindir],[path to pd bin dir]), [ pdbindir="${withval}" LIBDIRS="$LIBDIRS $withval" AS_IF([test -z "${EXTDIR}"], EXTDIR="${withval}/../extra") ],[ AS_IF([test -n "${win}"], AC_MSG_ERROR(path to pd bin dir required)) ]) # RTE CPPFLAGS_tmp="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} -I${sdkdir}" AS_CASE([$SYSTEM], [max], [ AC_DEFINE(FLEXT_SYS,1) # check for MaxAPI.h in pd folder AC_CHECK_HEADER([max-includes/MaxAPI.h],,AC_MSG_ERROR([Cannot find $sdkdir/max-includes/MaxAPI.h])) AC_CHECK_HEADER([max-includes/MaxAudioAPI.h],,AC_MSG_ERROR([Cannot find $sdkdir/max-includes/MaxAudioAPI.h])) INCLUDEDIRS="$INCLUDEDIRS $sdkdir/max-includes $sdkdir/msp-includes" pddll="" ], [pd], [ AC_DEFINE(FLEXT_SYS,2) # check for g_canvas.h in pd folder AC_CHECK_HEADER([g_canvas.h],,AC_MSG_ERROR([Cannot find $sdkdir/g_canvas.h]),[ #include "m_pd.h" ]) INCLUDEDIRS="$INCLUDEDIRS $sdkdir" pddll=pd pdfun=class_new ], [pd64], [ AC_DEFINE(FLEXT_SYS,2) # check for g_canvas.h in pd folder AC_CHECK_HEADER([g_canvas.h],,AC_MSG_ERROR([Cannot find $sdkdir/g_canvas.h]),[ #include "m_pd.h" ]) INCLUDEDIRS="$INCLUDEDIRS $sdkdir" pddll=pd64 pdfun=class_new64 AC_DEFINE([PD_FLOATSIZE], 64, [size of Pd floats (in bits)]) FLEXT_EXT_CFLAGS="$FLEXT_EXT_CFLAGS -DPD_FLOATSIZE=64"], [ AC_MSG_ERROR([system must be pd or max]) ]) LIBS_tmp="${LIBS}" AS_IF([test -n "${pddll}" && test -n "${win}"], LIBS="${LIBS} -L${pdbindir}" AC_CHECK_LIB([:${pddll}.dll], [$pdfun], [], [AC_MSG_ERROR([Cannot find/use $pdbindir/$pddll.dll])]) libs="$libs pddll" AC_DEFINE([NT]) ) CPPFLAGS="${CPPFLAGS_tmp}" LIBS="${LIBS_tmp}" ## atomic_ops CPPFLAGS_tmp="${CPPFLAGS}" AC_ARG_WITH(atomic_ops, AS_HELP_STRING([--with-atomic_ops],[path to atomic_ops library (needed for gcc version < 4.1 on non-i386 cpus)]), [ CPPFLAGS="${CPPFLAGS} -I${withval}" AC_CHECK_HEADER([atomic_ops.h],,AC_MSG_ERROR([Cannot find $withval/atomic_ops.h])) INCLUDEDIRS="$INCLUDEDIRS $withval" AC_DEFINE(USE_ATOMIC_OPS) ] ) CPPFLAGS="${CPPFLAGS_tmp}" ## STK CPPFLAGS_tmp="${CPPFLAGS}" AC_ARG_WITH(stkdir, AS_HELP_STRING([--with-stkdir],[path to STK headers]), [ CPPFLAGS="${CPPFLAGS} -I${withval}" AC_CHECK_HEADER([Stk.h],,AC_MSG_ERROR([Cannot find $withval/Stk.h])) stkdir=$withval INCLUDEDIRS="$INCLUDEDIRS $withval" ] ) AM_CONDITIONAL([STK],[test "$stkdir"]) CPPFLAGS="${CPPFLAGS_tmp}" ## SndObj CPPFLAGS_tmp="${CPPFLAGS}" AC_ARG_WITH(sndobjdir, AS_HELP_STRING([--with-sndobjdir],[path to SndObj headers]), [ CPPFLAGS="${CPPFLAGS} -I${withval}" AC_CHECK_HEADER([SndObj.h],,AC_MSG_ERROR([Cannot find $withval/SndObj.h])) sndobjdir=$withval INCLUDEDIRS="$INCLUDEDIRS $withval" ] ) AM_CONDITIONAL([SNDOBJ],[test "$sndobjdir"]) CPPFLAGS="${CPPFLAGS_tmp}" # if CFLAGS aren't set by the user, set them to an empty string # otherwise AC_PROG_CC sets them to "-O2 -g" test ".$CFLAGS" = "." && CFLAGS=" " test ".$CXXFLAGS" = "." && CXXFLAGS=" " AC_ENABLE_STATIC([]) AC_ENABLE_SHARED([]) # Checks for programs. AC_PROG_CC AC_PROG_CXX LT_INIT AC_PROG_INSTALL AC_PROG_MAKE_SET # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T AC_STRUCT_TM # Checks for library functions. # system specific AS_CASE([$host], [*linux*|*kfreebsd*gnu*],[ C_FLAGS="$C_FLAGS -fPIC" LD_FLAGS="$LD_FLAGS -shared" EXTENSION=pd_linux ], [*darwin*],[ FRAMEWORKS="$FRAMEWORKS ApplicationServices Accelerate" LD_FLAGS="$LD_FLAGS -flat_namespace -undefined dynamic_lookup" EXTENSION=pd_darwin ], [*mingw*|*cygwin*], [ C_FLAGS="$C_FLAGS -mms-bitfields -mno-cygwin" LD_FLAGS="$LD_FLAGS -mno-cygwin" EXTENSION=dll ], [ # default: like linux (but require extension via the --with-extension flag) C_FLAGS="$C_FLAGS -fPIC" LD_FLAGS="$LD_FLAGS -shared" #EXTENSION= ]) # In case of pd64, forget default extension definitions AS_IF([test "${SYSTEM}" == pd64], [EXTENSION=]) # A new extension format .${os}_${arch}_${floatsize}.${sysext} is needed, # which (for now) must be explicitly given through the --with-extension option AC_ARG_WITH([extension], AS_HELP_STRING([--with-extension=dll],[use the given extension instead of the platform-specific default]), AS_CASE([$withval], [yes|no|""], [], [EXTENSION=$withval])) AC_MSG_CHECKING([extension]) AS_IF([test -z "${EXTENSION}"], AC_MSG_ERROR([Unable to autodetect extension and none given... (pd64 system currently requires --with-extension)])) AC_MSG_RESULT([${EXTENSION}]) AS_IF([test -z "${EXTDIR}"], EXTDIR="/usr/local/lib/pd-externals") # set compilation flags OPT_FLAGS="$C_FLAGS -O3" DBG_FLAGS="$C_FLAGS -DFLEXT_DEBUG -g" AC_ARG_ENABLE(optimize, AS_HELP_STRING([--enable-optimize],[enables optimized architecture specific builds for pentium4, pentium3, G4, G5, etc.]), [ # tune to a specific CPU OPT_FLAGS="$OPT_FLAGS -mtune=$enableval" AS_CASE([$enableval], [pentium|pentium2|athlon|pentium-mmx],[ OPT_FLAGS="$OPT_FLAGS -march=$enableval" ],[pentium3|pentium3m|pentium4|pentium4m|pentium-m|prescott|nocona|athlon-xp|athlon-mp|athlon64|opteron],[ OPT_FLAGS="$OPT_FLAGS -march=$enableval -mfpmath=sse" AC_DEFINE(FLEXT_USE_SIMD) ],[G3],[ # set specific architecture (like march) OPT_FLAGS="$OPT_FLAGS -mcpu=$enableval" ],[G5|G4],[ # set specific architecture (like march) OPT_FLAGS="$OPT_FLAGS -mcpu=$enableval -faltivec" AC_DEFINE(FLEXT_USE_SIMD) ]) ] ) AC_ARG_ENABLE([cmem], AS_HELP_STRING([--enable-cmem],[enables C-style memory allocation (as opposed to overloading 'new' and 'delete')]), AS_CASE([$enableval], [yes], [ AC_DEFINE(FLEXT_USE_CMEM) FLEXT_EXT_CFLAGS="$FLEXT_EXT_CFLAGS -DFLEXT_USE_CMEM"]) ) AC_SUBST(SYSTEM) AC_SUBST(INCLUDEDIRS) AC_SUBST(LIBDIRS) AC_SUBST(OPT_FLAGS) AC_SUBST(DBG_FLAGS) AC_SUBST(LD_FLAGS) # AC_SUBST(API_VERSION) AC_SUBST(libs) AC_SUBST(stkdir) AC_SUBST(sndobjdir) AC_SUBST(FRAMEWORKS) AC_SUBST(FLEXT_EXT_CFLAGS) AC_SUBST(EXTENSION) AC_SUBST(EXTDIR) AC_CONFIG_FILES([ $SYSTEM-flext.pc Makefile source/Makefile tutorial/Makefile tutorial/1_simple1/Makefile tutorial/1_simple2/Makefile tutorial/1_simple3/Makefile tutorial/2_adv1/Makefile tutorial/2_adv2/Makefile tutorial/2_adv3/Makefile tutorial/3_attr1/Makefile tutorial/3_attr2/Makefile tutorial/3_attr3/Makefile tutorial/4_bind1/Makefile tutorial/4_buffer1/Makefile tutorial/4_timer1/Makefile tutorial/5_signal1/Makefile tutorial/5_signal2/Makefile tutorial/6_lib1/Makefile tutorial/7_thread1/Makefile tutorial/7_thread2/Makefile tutorial/8_sndobj1/Makefile tutorial/8_stk1/Makefile tutorial/8_stk2/Makefile tutorial/pd/Makefile tutorial/maxmsp/Makefile ]) AC_OUTPUT flext-0-6-3/gpl.txt000066400000000000000000000431311446466241400142000ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. flext-0-6-3/license.txt000066400000000000000000000015421446466241400150400ustar00rootroot00000000000000flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (C) 2001-2005 Thomas Grill This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. In the official flext distribution, the GNU General Public License is in the file gpl.txtflext-0-6-3/max-flext.pc.in000066400000000000000000000004011446466241400155040ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/flext Name: max-flext Description: C++ glue layer for Pure Data and Max Version: @VERSION@ Cflags: -I${includedir} -DFLEXT_SYS=1 -DFLEXT_SHARED Libs: -L${libdir} -lflext-max flext-0-6-3/notes.txt000066400000000000000000000051751446466241400145540ustar00rootroot00000000000000flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001-2023 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ---------------------------------------------------------------------------- VARIOUS NOTES: Platform specific: - Pd does not allow signal and message to go into the same inlet (except leftmost inlet) - Pd: with DSP objects all float messages to the leftmost inlet are converted to signal Restrictions in compatibility mode: - Max allows only 9 float/int inlets Porting to new compilers/platforms: - enums must be int-sized!!! - compiler must support bool type - an STL implementation must exist - C++ exceptions and RTTI must be enabled ---------------------------------------------------------------------------- KNOWN BUGS: - Some few external libraries have troubles with flext's global new and delete overloadings. In these cases one can switch back to the C library memory operators by defining the FLEXT_NOGLOBALNEW macro before inclusion of the flext.h header file (e.g. as a -D compiler option) - Pd: floats into the leftmost inlet of DSP objects can't be used as messages even if there's no signal inlet at all ---------------------------------------------------------------------------- TODO LIST: - optimizations for object initialization and messaging - speed up message handling (usage of other containers?) - SIMD for gcc - lock-free code for old AMD 64-bit architectures - update documentation - add log messages for debugging version - use Pd's t_float and t_int types (or comparable for 32-bit safety) - add double handlers - add signal in/out connection query function - support for Max qelem style - flext::post and flext::error should print via a worker thread (and should be unlimited in characters) - manage running threads individually (stop, isrunning?, priority etc.) ---------------------------------------------------------------------------- TESTS TO DO: - Pd: problems with timed buffer redrawing (takes a lot of cpu time) - hard thread termination upon object destruction doesn't seem to work properly -> crash - Max rounding bug ... buffer resize could be one sample less! - Pd: figure out what "pointer" messages do and whether they are correctly implemented in flext - Max buffer~ resize: flext_base::buffer::Frames(): must we use buffer or system sample rate? - check whether m_dsp gets called upon deletion of a used buffer (Pd and MaxMSP may behave differently). -> Pd does call m_dsp, Max/MSP does not flext-0-6-3/package.txt000066400000000000000000000030701446466241400150070ustar00rootroot00000000000000# # flext - C++ layer for Max and Pd (Pure data) externals # # Copyright (c) 2001-2023 Thomas Grill (gr@grrrr.org) # # $LastChangedRevision$ # $LastChangedDate$ # $LastChangedBy$ # # For information on usage and redistribution, and for a DISCLAIMER OF ALL # WARRANTIES, see the file, "license.txt," in this distribution. # # more information on http://grrrr.org/ext # ------------------------------------------------------------------------ # # This file contains information for the building process # # DO NOT EDIT!! # # ------------------------------------------------------------------------ NAME=flext BUILDCLASS=flext BUILDMODE=all BUILDTYPE=all BUILDDIR=build SRCDIR=source PRECOMPILE=flext.h SRCS= \ flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp \ flxlet.cpp flattr.cpp flattr_ed.cpp flsupport.cpp \ flutil.cpp flatom.cpp flatom_pr.cpp flthr.cpp fltimer.cpp flsimd.cpp flout.cpp \ flatom_part.cpp flitem.cpp flmeth.cpp flmsg.cpp \ flproxy.cpp flqueue.cpp flbind.cpp flmap.cpp HDRS= \ flext.h flprefix.h flstdc.h flinternal.h flfeatures.h \ flpushns.h flpopns.h \ flbase.h flclass.h flsupport.h fldsp.h \ flmap.h flcontainers.h \ fldefs.h fldefs_hdr.h fldefs_setup.h \ fldefs_methcb.h fldefs_meththr.h fldefs_methadd.h fldefs_methbind.h fldefs_methcall.h \ fldefs_attrcb.h fldefs_attrvar.h fldefs_attradd.h \ lockfree/prefix.hpp lockfree/cas.hpp lockfree/branch_hints.hpp \ lockfree/atomic_int.hpp lockfree/atomic_ptr.hpp \ lockfree/fifo.hpp lockfree/stack.hpp SRCS_SNDOBJ=flsndobj.cpp HDRS_SNDOBJ=flsndobj.h SRCS_STK=flstk.cpp HDRS_STK=flstk.h flext-0-6-3/pd-flext.pc.in000066400000000000000000000013131446466241400153250ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/flext Name: @SYSTEM@-flext Description: C++ glue layer for Pure Data and Max Version: @VERSION@ Requires: pd Cflags: -I${includedir} -DFLEXT_SYS=2 -DFLEXT_SHARED @FLEXT_EXT_CFLAGS@ -pthread Libs: -L${libdir} -lflext-@SYSTEM@ -pthread ## sections below ought to be factored out into standalone .pc files #Name: pd-flext-static #Description: C++ glue layer for Pure Data and Max (static) #Version: @VERSION@ #Cflags: -I${includedir} -DPD #Libs: -L${libdir} -lflext-@SYSTEM@_s # #Name: pd-flext-inline #Description: C++ glue layer for Pure Data and Max (inline) #Version: @VERSION@ #Cflags: -I${includedir} -DPD -DFLEXT_INLINE #Libs: flext-0-6-3/pd64-flext.pc.in000077700000000000000000000000001446466241400201502pd-flext.pc.inustar00rootroot00000000000000flext-0-6-3/readme.txt000066400000000000000000000072661446466241400146640ustar00rootroot00000000000000flext - C++ layer for Max/MSP and Pd (Pure Data) externals Copyright (c) 2001-2023 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. This package seeks to encourage the development of open source software for the pd and Max/MSP platforms. Donations for further development of the package are highly appreciated. https://www.paypal.com/xclick/business=gr%40grrrr.org&item_name=flext&no_note=1&tax=0¤cy_code=EUR ---------------------------------------------------------------------------- Abstract: flext seeks to represent a uniform programming interface for extending the most common modular real-time audio systems Max/MSP and Pure Data (Pd) with external modules, or short externals. These modules provide a way to tailor such a system for oneís special needs and supply additional functionality. Source code based on flext is able to exploit most common features of the respective real-time framework while staying completely independent of the actual host system and platform (hardware and operating system). flext currently supports development for Pd under Linux, Windows and OSX as well as Max/MSP under OS9, OSX and Windows with various programming environments. ---------------------------------------------------------------------------- Goals/features of the package: pros: - better readability of code compared to straight C externals - faster development, more robust coding - sharing of common methods and data by using base classes - any input to any inlet (with the exception of signal streams) - transparent use of threads for methods - libraries of externals in Max/MSP - more than 3 typed creation arguments possible for Max/MSP cons: - introduces a small overhead to speed of message and signal handling - larger memory footprint ---------------------------------------------------------------------------- Prerequisites: --- Pd --- You need the pd source code which is most likely part of the distribution. Otherwise download from: http://msp.ucsd.edu/software.html --- Max/MSP --- You will need the latest Max/MSP SDK: https://cycling74.com/downloads/sdk --- SndObj --- If you choose to compile with SndObj support you will need the respective library download from: http://www.may.ie/academic/music/musictec/SndObj/main.html --- STK --- If you choose to compile with STK support you will need the respective package and build a library. download from: https://ccrma.stanford.edu/software/stk/ For linking it may preferable to use a library of all the STK objects. Under linux you can create one from the STK directory with something like > g++ -c -pipe -I include -D __LINUX_OSS__ src/*.cpp && ar r libstk.a *.o && rm -f *.o Under Windows you can build a static STK library with the following commands: > cl src/*.c* /MT /D__OS_WINDOWS__ /EHsc /Ox /Iinclude /I../pthreads/include /c > lib *.obj /out:stk.lib Please note, that you have to have pthreads installed (../pthreads points to it in the command) Also, the resulting stk.lib will be a multithreaded build, linked to a static C library. Consequently you should also use multithreaded flext for your flext-based external. ---------------------------------------------------------------------------- Building and installing of flext and flext-based externals: See the build.txt document ---------------------------------------------------------------------------- Various notes / limitations / bug list: Read the notes.txt document ---------------------------------------------------------------------------- History of changes: Read the changes.txt document flext-0-6-3/source/000077500000000000000000000000001446466241400141535ustar00rootroot00000000000000flext-0-6-3/source/Makefile.am000066400000000000000000000057461446466241400162230ustar00rootroot00000000000000# # automake template # added by tim blechmann # added by Thomas Grill # # static libraries #lib_LIBRARIES = # shared libraries lib_LTLIBRARIES = libflext-@SYSTEM@_s.la libflext-@SYSTEM@_sd.la libflext-@SYSTEM@_t.la libflext-@SYSTEM@_td.la libflext-@SYSTEM@.la libflext-@SYSTEM@_d.la # x:y:z -> .so.(x-z).z.y # .so.A.B.C -> (A+B):C:B # VERSION_INFO = -version-info 6:2:6 SRCS_FLEXT = \ flbase.cpp \ flext.cpp \ flbuf.cpp \ fldsp.cpp \ fllib.cpp \ flxlet.cpp \ flattr.cpp \ flattr_ed.cpp \ flsupport.cpp \ flutil.cpp \ flthr.cpp \ fltimer.cpp \ flsimd.cpp \ flout.cpp \ flatom.cpp \ flatom_pr.cpp \ flatom_part.cpp \ flitem.cpp \ flmeth.cpp \ flmsg.cpp \ flproxy.cpp \ flqueue.cpp \ flbind.cpp \ flmap.cpp nobase_pkginclude_HEADERS = \ flprefix.h \ flstdc.h \ flbase.h \ flclass.h \ flext.h \ flfeatures.h \ flsupport.h \ flmap.h \ fldsp.h \ flmspbuffer.h \ flinternal.h \ flcontainers.h \ flpushns.h \ flpopns.h \ fldefs.h \ fldefs_hdr.h \ fldefs_setup.h \ fldefs_methcb.h \ fldefs_meththr.h \ fldefs_methadd.h \ fldefs_methbind.h \ fldefs_methcall.h \ fldefs_attrcb.h \ fldefs_attrvar.h \ fldefs_attradd.h \ lockfree/prefix.hpp \ lockfree/branch_hints.hpp \ lockfree/cas.hpp \ lockfree/atomic_int.hpp \ lockfree/atomic_ptr.hpp \ lockfree/fifo.hpp \ lockfree/stack.hpp \ $(SRCS_FLEXT) # handling for stk / sndobj SRCS_STK = flstk.cpp HDRS_STK = flstk.h SRCS_SNDOBJ = flsndobj.cpp HDRS_SNDOBJ = flsndobj.h if SNDOBJ SRCS_FLEXT += $(SRCS_SNDOBJ) nobase_pkginclude_HEADERS += $(HDRS_SNDOBJ) LIB_SNDOBJ = sndobj endif if STK SRCS_FLEXT += $(SRCS_STK) nobase_pkginclude_HEADERS += $(HDRS_STK) LIB_STK = stk endif libflext_@SYSTEM@_s_la_SOURCES = $(SRCS_FLEXT) libflext_@SYSTEM@_sd_la_SOURCES = $(SRCS_FLEXT) libflext_@SYSTEM@_t_la_SOURCES = $(SRCS_FLEXT) libflext_@SYSTEM@_td_la_SOURCES = $(SRCS_FLEXT) libflext_@SYSTEM@_la_SOURCES = $(SRCS_FLEXT) libflext_@SYSTEM@_d_la_SOURCES = $(SRCS_FLEXT) libflext_@SYSTEM@_s_la_CXXFLAGS = @OPT_FLAGS@ -static $(patsubst %,-I%,@INCLUDEDIRS@) libflext_@SYSTEM@_sd_la_CXXFLAGS = @DBG_FLAGS@ -static $(patsubst %,-I%,@INCLUDEDIRS@) libflext_@SYSTEM@_t_la_CXXFLAGS = @OPT_FLAGS@ -static $(patsubst %,-I%,@INCLUDEDIRS@) -DFLEXT_THREADS libflext_@SYSTEM@_td_la_CXXFLAGS = @DBG_FLAGS@ -static $(patsubst %,-I%,@INCLUDEDIRS@) -DFLEXT_THREADS libflext_@SYSTEM@_la_CXXFLAGS = @OPT_FLAGS@ $(patsubst %,-I%,@INCLUDEDIRS@) -DFLEXT_SHARED -DFLEXT_EXPORTS libflext_@SYSTEM@_d_la_CXXFLAGS = @DBG_FLAGS@ $(patsubst %,-I%,@INCLUDEDIRS@) -DFLEXT_SHARED -DFLEXT_EXPORTS libflext_@SYSTEM@_la_LDFLAGS = @LD_FLAGS@ $(patsubst %,-L%,@LIBDIRS@) $(patsubst %,-l%,@libs@ $(LIB_SNDOBJ) $(LIB_STK)) $(patsubst %,-framework %,@FRAMEWORKS@) $(VERSION_INFO) libflext_@SYSTEM@_d_la_LDFLAGS = @LD_FLAGS@ $(patsubst %,-L%,@LIBDIRS@) $(patsubst %,-l%,@libs@ $(LIB_SNDOBJ) $(LIB_STK)) $(patsubst %,-framework %,@FRAMEWORKS@) $(VERSION_INFO) #libflext_@SYSTEM@_la_LIBADD = @libs@ #libflext_@SYSTEM@_d_la_LIBADD = @libs@ flext-0-6-3/source/flatom.cpp000066400000000000000000000110441446466241400161410ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flatom.cpp \brief Definitions for handling the t_atom type and lists thereof. */ #ifndef __FLEXT_ATOM_CPP #define __FLEXT_ATOM_CPP #include "flext.h" #include // for memcpy #include "flpushns.h" FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::CmpAtom(const t_atom &a,const t_atom &b) { if(GetType(a) == GetType(b)) { switch(GetType(a)) { case A_FLOAT: return GetFloat(a) == GetFloat(b)?0:(GetFloat(a) < GetFloat(b)?-1:1); #if FLEXT_SYS == FLEXT_SYS_MAX case A_INT: return GetInt(a) == GetInt(b)?0:(GetInt(a) < GetInt(b)?-1:1); #endif case A_SYMBOL: return GetSymbol(a) == GetSymbol(b)?0:strcmp(GetString(a),GetString(b)); #if FLEXT_SYS == FLEXT_SYS_PD case A_POINTER: return GetPointer(a) == GetPointer(b)?0:(GetPointer(a) < GetPointer(b)?-1:1); #endif default: // can't be compared..... FLEXT_ASSERT(false); return 0; } } else return GetType(a) < GetType(b)?-1:1; } FLEXT_TEMPIMPL(t_atom *FLEXT_CLASSDEF(flext))::CopyList(int argc,const t_atom *argv) { t_atom *dst = new t_atom[argc]; memcpy(dst,argv,argc*sizeof(t_atom)); return dst; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::CopyAtoms(int cnt,t_atom *dst,const t_atom *src) { if(dst < src) // forward memcpy(dst,src,cnt*sizeof(t_atom)); else // backwards while(cnt--) dst[cnt] = src[cnt]; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::AtomList::Alloc(int sz,int keepix,int keeplen,int keepto) { if(lst) { if(cnt == sz) { if(keepix >= 0 && keepix != keepto) { int c = keeplen >= 0?keeplen:cnt; FLEXT_ASSERT(c+keepto <= cnt); FLEXT_ASSERT(c+keepix <= cnt); CopyAtoms(c,lst+keepto,lst+keepix); } return; // no change } t_atom *l; if(sz) { l = new t_atom[sz]; if(keepix >= 0) { // keep contents int c = keeplen >= 0?keeplen:(cnt > sz?sz:cnt); FLEXT_ASSERT(c+keepto <= sz); FLEXT_ASSERT(c+keepix <= cnt); CopyAtoms(c,l+keepto,lst+keepix); } } else l = NULL; Free(); lst = l,cnt = sz; } else { FLEXT_ASSERT(cnt == 0); if(sz) lst = new t_atom[cnt = sz]; } } FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext))::AtomList::~AtomList() { Free(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::AtomList::Free() { if(lst) { delete[] lst; lst = NULL; cnt = 0; } else FLEXT_ASSERT(cnt == 0); } FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext))::AtomList &FLEXT_CLASSDEF(flext))::AtomList::Set(int argc,const t_atom *argv,int offs,bool resize) { int ncnt = argc+offs; if(resize) Alloc(ncnt); // argv can be NULL independently from argc if(argv) CopyAtoms(argc,lst+offs,argv); return *this; } FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::AtomList::Compare(const AtomList &a) const { if(Count() == a.Count()) { for(int i = 0; i < Count(); ++i) { int cmp = CmpAtom(lst[i],a[i]); if(cmp) return cmp; } return 0; } else return Count() < a.Count()?-1:1; } FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext))::AtomListStaticBase::~AtomListStaticBase() { Free(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::AtomListStaticBase::Alloc(int sz,int keepix,int keeplen,int keepto) { if(sz <= precnt) { // small enough for pre-allocated space if(AtomList::lst != predata && AtomList::lst) { // currently allocated memory is larger than what we need if(keepix >= 0) { // keep contents int c = keeplen >= 0?keeplen:(AtomList::cnt > sz?sz:AtomList::cnt); FLEXT_ASSERT(c+keepto <= precnt); FLEXT_ASSERT(c+keepix <= AtomList::cnt); CopyAtoms(c,predata+keepto,AtomList::lst+keepix); } // free allocated memory AtomList::Free(); } AtomList::lst = predata; AtomList::cnt = sz; } else AtomList::Alloc(sz,keepix,keeplen,keepto); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::AtomListStaticBase::Free() { if(AtomList::lst != predata) AtomList::Free(); else { AtomList::lst = NULL; AtomList::cnt = 0; } } #include "flpopns.h" #endif // __FLEXT_ATOM_CPP flext-0-6-3/source/flatom_part.cpp000066400000000000000000000017141446466241400171720ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flatom_part.cpp \brief Definitions for handling the t_atom type and lists thereof. */ #ifndef __FLEXT_ATOM_PART_CPP #define __FLEXT_ATOM_PART_CPP #include "flext.h" #include "flpushns.h" FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::AtomList::Get(t_atom *argv,int mxsz) const { int argc = Count(); if(mxsz >= 0 && argc > mxsz) argc = mxsz; for(int i = 0; i < argc; ++i) SetAtom(argv[i],lst[i]); return argc; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::AtomList::GetPart(int offs,int len,AtomList &ret) const { if(offs+len > Count()) { len = Count()-offs; if(len < 0) len = 0; } ret(len,Atoms()+offs); } #include "flpopns.h" #endif // __FLEXT_ATOM_PART_CPP flext-0-6-3/source/flatom_pr.cpp000066400000000000000000000061451446466241400166500ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flatom_pr.cpp \brief Definitions for printing and scanning the t_atom type. */ #ifndef __FLEXT_ATOM_PR_CPP #define __FLEXT_ATOM_PR_CPP #include "flext.h" #include #include #include #include #include "flpushns.h" #ifdef _MSC_VER #define snprintf _snprintf #endif FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::PrintAtom(const t_atom &a,char *buf,size_t bufsz) { bool ok = true; if(IsFloat(a)) { ok = STD::snprintf(buf,bufsz,"%g",GetFloat(a)) > 0; } else if(IsInt(a)) { ok = STD::snprintf(buf,bufsz,"%i",GetInt(a)) > 0; } else if(IsSymbol(a)) { const char *c = GetString(a); size_t len = strlen(c); if(len < bufsz) { memcpy(buf,c,len); buf[len] = 0; ok = true; } else ok = false; } #if FLEXT_SYS == FLEXT_SYS_PD #ifndef FLEXT_COMPATIBLE else if(IsPointer(a)) { ok = STD::snprintf(buf,bufsz,"%p",GetPointer(a)) > 0; } #endif else if(a.a_type == A_DOLLAR) { ok = STD::snprintf(buf,bufsz,"$%d",a.a_w.w_index) > 0; } else if(a.a_type == A_DOLLSYM) { ok = STD::snprintf(buf,bufsz,"$%s",GetString(a)) > 0; } #elif FLEXT_SYS == FLEXT_SYS_MAX else if(a.a_type == A_DOLLAR) { ok = STD::snprintf(buf,bufsz,"$%ld",a.a_w.w_long) > 0; } #else //#pragma message("Not implemented") #endif else { error("flext: atom type unknown"); ok = false; } return ok; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::PrintList(int argc,const t_atom *argv,char *buf,size_t bufsz) { bool ok = true; for(int i = 0; ok && i < argc && bufsz > 0; ++i) { if(i) { *(buf++) = ' '; --bufsz; } // prepend space if(PrintAtom(argv[i],buf,bufsz)) { size_t len = strlen(buf); buf += len; bufsz -= len; } else ok = false; } *buf = 0; return ok; } FLEXT_TEMPIMPL(const char *FLEXT_CLASSDEF(flext))::ScanAtom(t_atom &a,const char *c) { // skip leading whitespace while(*c && isspace(*c)) ++c; if(!*c) return NULL; // go to next space and save character char *end = const_cast(c); while(*end && !isspace(*end)) ++end; char sv = *end; float fres; // first try float char *endp; // see if it's a float - thanks to Frank Barknecht fres = (float)strtod(c,&endp); if(*c && endp != c) { int ires = (int)fres; // try a cast if(fres == ires) SetInt(a,ires); else SetFloat(a,fres); } // no, it's a symbol else SetString(a,c); *end = sv; return end; } FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::ScanList(int argc,t_atom *argv,const char *buf) { int read; for(read = 0; read < argc; ++read) { buf = ScanAtom(argv[read],buf); if(!buf) break; } return read; } #include "flpopns.h" #endif // __FLEXT_ATOM_PR_CPP flext-0-6-3/source/flattr.cpp000066400000000000000000000260611446466241400161600ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flattr.cpp \brief Attribute handling for the flext base class */ #ifndef __FLEXT_ATTR_CPP #define __FLEXT_ATTR_CPP #include "flext.h" #include #include #include #include "flpushns.h" #ifdef __MWERKS__ #define STD std #else #define STD #endif FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::AttrItem::AttrItem(const t_symbol *t,int tp,methfun f,int fl): Item(NULL),index(0), flags(fl|afl_shown), argtp(tp),fun(f), counter(NULL),tag(t) {} /* FLEXT_CLASSDEF(flext_base)::AttrDataCont::AttrDataCont() {} FLEXT_CLASSDEF(flext_base)::AttrDataCont::~AttrDataCont() { for(iterator it = begin(); it != end(); ++it) if(it.data()) delete it.data(); } */ FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::AttrDataCont::~AttrDataCont() { clear(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AttrDataCont::clear() { for(FLEXT_TEMP_TYPENAME AttrDataCont::iterator it(*this); it; ++it) delete it.data(); TablePtrMap::clear(); } //! Add get and set attributes FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddAttrib(ItemCont *aa,ItemCont *ma,const t_symbol *asym,int tp,methfun gfun,methfun sfun) { AttrItem *a,*b; FLEXT_ASSERT(asym != sym__ && asym != sym_list && asym != sym_float && asym != sym_symbol && asym != sym_anything); if(sfun) // if commented out, there will be a warning at run-time (more user-friendly) { a = new AttrItem(asym,tp,sfun,AttrItem::afl_set); a->index = aa->Members(); aa->Add(a,asym); // bind attribute to a method MethItem *mi = new MethItem(a); mi->SetArgs(sfun,1,new int(tp)); ma->Add(mi,asym); } else a = NULL; if(gfun) // if commented out, there will be a warning at run-time (more user-friendly) { b = new AttrItem(asym,tp,gfun,AttrItem::afl_get); b->index = aa->Members(); aa->Add(b,asym); static char tmp[256] = "get"; strcpy(tmp+3,GetString(asym)); // bind attribute to a method MethItem *mi = new MethItem(b); mi->SetArgs(gfun,0,NULL); ma->Add(mi,MakeSymbol(tmp)); } else b = NULL; if(a && b) { a->counter = b; b->counter = a; } } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddAttrib(const t_symbol *attr,int tp,methfun gfun,methfun sfun) { if(HasAttributes()) AddAttrib(ThAttrs(),ThMeths(),attr,tp,gfun,sfun); else error("%s - attribute procession is not enabled!",thisName()); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddAttrib(t_classid c,const t_symbol *attr,int tp,methfun gfun,methfun sfun) { AddAttrib(ClAttrs(c),ClMeths(c),attr,tp,gfun,sfun); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ListAttrib(AtomList &la) const { typedef TablePtrMap AttrList; AttrList list[2]; ItemCont *clattrhead = ClAttrs(thisClassId()); int i; for(i = 0; i <= 1; ++i) { ItemCont *a = i?attrhead:clattrhead; if(a && a->Contained(0)) { ItemSet &ai = a->GetInlet(); for(FLEXT_TEMP_TYPENAME ItemSet::iterator as(ai); as; ++as) { for(Item *al = as.data(); al; al = al->nxt) { AttrItem *aa = (AttrItem *)al; list[i].insert(aa->index,as.key()); break; } } } } la((int)(list[0].size()+list[1].size())); int ix = 0; for(i = 0; i <= 1; ++i) for(AttrList::iterator it(list[i]); it; ++it) SetSymbol(la[ix++],it.data()); } FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext_base))::CheckAttrib(int argc,const t_atom *argv) { int offs = 0; for(; offs < argc; ++offs) if(IsString(argv[offs]) && *GetString(argv[offs]) == '@') break; return offs; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::InitAttrib(int argc,const t_atom *argv) { int cur,nxt; for(cur = 0; cur < argc; cur = nxt) { // find next @symbol for(nxt = cur+1; nxt < argc; ++nxt) if(IsString(argv[nxt]) && *GetString(argv[nxt]) == '@') break; const t_symbol *tag = MakeSymbol(GetString(argv[cur])+1); // find puttable attribute AttrItem *attr = FindAttrib(tag,false,true); if(attr) { // make an entry (there are none beforehand...) /* AttrDataCont::iterator it = attrdata->find(tag); if(it == attrdata->end()) { AttrDataCont::pair pair; pair.key() = tag; pair.data() = new AttrData; it = attrdata->insert(attrdata->begin(),pair); } AttrData &a = *it.data(); a.SetInit(true); a.SetInitValue(nxt-cur-1,argv+cur+1); // pass value to object SetAttrib(tag,attr,a.GetInitValue()); */ AttrData *a = attrdata->find(tag); if(!a) { AttrData *old = attrdata->insert(tag,a = new AttrData); FLEXT_ASSERT(!old); } a->SetInit(true); a->SetInitValue(nxt-cur-1,argv+cur+1); // pass value to object SetAttrib(tag,attr,a->GetInitValue()); } } return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::ListAttrib() const { if(HasAttributes()) { // defined in flsupport.cpp AtomListStatic<32> la; ListAttrib(la); ToOutAnything(GetOutAttr(),sym_attributes,la.Count(),la.Atoms()); return true; } else return false; } FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext_base))::AttrItem *FLEXT_CLASSDEF(flext_base))::FindAttrib(const t_symbol *tag,bool get,bool msg) const { ItemCont *clattrhead = ClAttrs(thisClassId()); // first search within object scope AttrItem *a = NULL; { for(Item *lst = attrhead->FindList(tag); lst; lst = lst->nxt) { AttrItem *b = (AttrItem *)lst; if(get?b->IsGet():b->IsSet()) { a = b; break; } } } // then (if nothing found) search within class scope if(!a) { for(Item *lst = clattrhead->FindList(tag); lst; lst = lst->nxt) { AttrItem *b = (AttrItem *)lst; if(get?b->IsGet():b->IsSet()) { a = b; break; } } } if(!a && msg) { // print a message error("%s - %s: attribute not found",thisName(),GetString(tag)); } return a; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::SetAttrib(const t_symbol *tag,int argc,const t_atom *argv) { // search for matching attribute AttrItem *a = FindAttrib(tag,false,true); return a && SetAttrib(tag,a,argc,argv); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::SetAttrib(const t_symbol *tag,AttrItem *a,int argc,const t_atom *argv) { if(a->fun) { bool ok = true; t_any any; switch(a->argtp) { case a_float: if(argc == 1 && CanbeFloat(argv[0])) { any.ft = GetAFloat(argv[0]); ((methfun_1)a->fun)(this,any); } else ok = false; break; case a_int: if(argc == 1 && CanbeInt(argv[0])) { any.it = GetAInt(argv[0]); ((methfun_1)a->fun)(this,any); } else ok = false; break; case a_symbol: if(argc == 1 && IsSymbol(argv[0])) { t_atom at; GetParamSym(at,GetSymbol(argv[0]),thisCanvas()); any.st = const_cast(GetSymbol(at)); ((methfun_1)a->fun)(this,any); } else ok = false; break; case a_bool: if(argc == 1 && CanbeBool(argv[0])) { any.bt = GetABool(argv[0]); ((methfun_1)a->fun)(this,any); } else ok = false; break; case a_LIST: { AtomListStatic<16> la(argc); for(int i = 0; i < argc; ++i) if(IsSymbol(argv[i])) GetParamSym(la[i],GetSymbol(argv[i]),thisCanvas()); else la[i] = argv[i]; any.vt = &la; ((methfun_1)a->fun)(this,any); break; } default: ERRINTERNAL(); } if(!ok) post("%s - wrong arguments for attribute %s",thisName(),GetString(tag)); } else post("%s - attribute %s has no get method",thisName(),GetString(tag)); return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::GetAttrib(const t_symbol *tag,AttrItem *a,AtomList &la) const { bool ok = true; // main attribute tag if(a) { if(a->fun) { t_any any; switch(a->argtp) { case a_float: { ((methfun_1)a->fun)(const_cast(this),any); la(1); SetFloat(la[0],any.ft); break; } case a_int: { ((methfun_1)a->fun)(const_cast(this),any); la(1); SetInt(la[0],any.it); break; } case a_bool: { ((methfun_1)a->fun)(const_cast(this),any); la(1); SetBool(la[0],any.bt); break; } case a_symbol: { ((methfun_1)a->fun)(const_cast(this),any); la(1); SetSymbol(la[0],any.st); break; } case a_LIST: { any.vt = &la; ((methfun_1)a->fun)(const_cast(this),any); break; } default: ERRINTERNAL(); ok = false; } } else { post("%s - attribute %s has no get method",thisName(),GetString(tag)); ok = false; } } else { error("%s - %s: attribute not found",thisName(),GetString(tag)); ok = false; } return ok; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::GetAttrib(const t_symbol *s,AtomList &a) const { AttrItem *attr = FindAttrib(s,true); return attr && GetAttrib(s,attr,a); } //! \param tag symbol "get[attribute]" FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::DumpAttrib(const t_symbol *tag,AttrItem *a) const { AtomListStatic<16> la; bool ret = GetAttrib(tag,a,la); if(ret) { ToOutAnything(GetOutAttr(),a->tag,la.Count(),la.Atoms()); } return ret; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::DumpAttrib(const t_symbol *attr) const { AttrItem *item = FindAttrib(attr,true); return item && DumpAttrib(attr,item); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::BangAttrib(const t_symbol *attr,AttrItem *item) { AtomListStatic<16> val; AttrItem *item2; if(!item->IsGet()) item = item->Counterpart(); if(item) { item2 = item->Counterpart(); return item2 && GetAttrib(attr,item,val) && SetAttrib(attr,item2,val); } else return false; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::BangAttrib(const t_symbol *attr) { AttrItem *item = FindAttrib(attr,true); return item && BangAttrib(attr,item); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::BangAttribAll() { ItemCont *clattrhead = ClAttrs(thisClassId()); for(int i = 0; i <= 1; ++i) { ItemCont *a = i?attrhead:clattrhead; if(a) { ItemSet &ai = a->GetInlet(); // \todo need to check for presence of inlet 0? for(FLEXT_TEMP_TYPENAME ItemSet::iterator as(ai); as; ++as) { for(Item *al = as.data(); al; al = al->nxt) { AttrItem *aj = (AttrItem *)al; if(aj->IsGet() && aj->BothExist()) BangAttrib(as.key(),aj); } } } } return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::ShowAttrib(AttrItem *a,bool show) const { if(show) a->flags |= AttrItem::afl_shown; else a->flags &= ~AttrItem::afl_shown; // also change counterpart, if present AttrItem *ca = a->Counterpart(); if(ca) { if(show) ca->flags |= AttrItem::afl_shown; else ca->flags &= ~AttrItem::afl_shown; } return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::ShowAttrib(const t_symbol *attr,bool show) const { AttrItem *item = FindAttrib(attr,true); return item && ShowAttrib(item,show); } #include "flpopns.h" #endif // __FLEXT_ATTR_CPP flext-0-6-3/source/flattr_ed.cpp000066400000000000000000000770471446466241400166420ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flattr_ed.cpp \brief Attribute editor (property dialog) for PD */ #ifndef __FLEXT_ATTR_ED_CPP #define __FLEXT_ATTR_ED_CPP #include "flext.h" #include "flpushns.h" #if FLEXT_SYS == FLEXT_SYS_PD #ifdef _MSC_VER #pragma warning( disable : 4091 ) #endif #if defined(FLEXT_ATTRHIDE) || PD_MINOR_VERSION < 37 #define __FLEXT_WIDGETBEHAVIOR #endif ////////////////////////////////////////////////////// #ifdef __FLEXT_WIDGETBEHAVIOR // we need non-public headers! #pragma message("Attention: non-public headers used - binary is bound to a specific version") #include /* #ifdef PD_DEVEL_VERSION #define __FLEXT_CLONEWIDGET #endif */ #ifndef __FLEXT_CLONEWIDGET #include #endif #endif ////////////////////////////////////////////////////// #include #include #ifdef FLEXT_ATTRHIDE #ifndef __FLEXT_CLONEWIDGET static t_visfn ori_vis = NULL; static t_selectfn ori_select = NULL; #endif #endif #ifdef FLEXT_ATTRHIDE #define ST_DISABLED "" #else #define ST_DISABLED " -state disabled" #endif #ifndef FLEXT_NOATTREDIT //! generate the script for the property dialog FLEXT_TEMPLATE void tclscript() { static bool havecode = false; if(havecode) return; else havecode = true; sys_vgui(const_cast( "proc flext_escatoms {lst} {\n" "set tmp {}\n" "foreach a $lst {\n" // "set a [regsub {\\\\} $a \\\\\\\\]\n" // replace \ with \\ ... must be first "set a [regsub {\\$} $a \\\\$]\n" // replace $ with \$ // "set a [regsub {\\{} $a \\\\\\{]\n" // replace { with \{ // "set a [regsub {\\}} $a \\\\\\}]\n" // replace } with \} // "set a [regsub {\\ } $a \\\\\\ ]\n" // replace space with \space "set a [regsub {,} $a \\\\,]\n" // replace , with \, "set a [regsub {;} $a \\\\\\;]\n" // replace ; with \; "lappend tmp $a\n" "}\n" "return $tmp\n" "}\n") ); sys_vgui(const_cast( "proc flext_makevalue {id ix} {\n" // strip "." from the TK id to make a variable name suffix "set vid [string trimleft $id .]\n" "set var_attr_name [concat [concat var_name_$ix]_$vid ]\n" "set var_attr_init [concat [concat var_init_$ix]_$vid ]\n" "set var_attr_val [concat [concat var_val_$ix]_$vid ]\n" "set var_attr_save [concat [concat var_save_$ix]_$vid ]\n" "set var_attr_type [concat [concat var_type_$ix]_$vid ]\n" "global $var_attr_name $var_attr_init $var_attr_val $var_attr_save $var_attr_type\n" "set lst {}\n" "if { [expr $$var_attr_type] != 0 } {\n" // attribute is puttable "lappend lst [eval concat $$var_attr_name]\n" // process current value "set tmp [flext_escatoms [eval concat $$var_attr_val]]\n" "set lst [concat $lst [llength $tmp] $tmp]\n" // process init value "set tmp [flext_escatoms [eval concat $$var_attr_init]]\n" "set lst [concat $lst [llength $tmp] $tmp]\n" "lappend lst [eval concat $$var_attr_save]\n" "}\n" // return list "return $lst\n" "}\n") ); sys_vgui(const_cast( "proc flext_apply {id ix} {\n" "set lst [flext_makevalue $id $ix]\n" "set lst [eval concat $lst]\n" // remove curly braces from character escaping "pd [concat $id attributedialog $lst \\;]\n" "}\n" "proc flext_applyall {id alen} {\n" // make a list of the attribute values (including save flags) "set lst {}\n" "for {set ix 1} {$ix <= $alen} {incr ix} {\n" "set lst [concat $lst [flext_makevalue $id $ix]]\n" "}\n" "set lst [eval concat $lst]\n" // remove curly braces from character escaping "pd [concat $id attributedialog $lst \\;]\n" "}\n" "proc flext_cancel {id} {\n" "pd [concat $id cancel \\;]\n" "}\n" "proc flext_ok {id alen} {\n" "flext_applyall $id $alen\n" "flext_cancel $id\n" "}\n") ); sys_vgui(const_cast( "proc flext_help {id} {\n" "toplevel $id.hw\n" "wm title $id.hw \"Flext attribute editor help\"\n" "frame $id.hw.buttons\n" "pack $id.hw.buttons -side bottom -fill x -pady 2m\n" "text $id.hw.text -relief sunken -bd 2 -yscrollcommand \"$id.hw.scroll set\" -setgrid 1 -width 80 -height 10 -wrap word\n" "scrollbar $id.hw.scroll -command \"$id.hw.text yview\"\n" "pack $id.hw.scroll -side right -fill y\n" "pack $id.hw.text -expand yes -fill both\n" "button $id.hw.buttons.ok -text OK -command \"destroy $id.hw\"\n" "pack $id.hw.buttons.ok -side left -expand 1\n" "bind $id.hw {} \"destroy $id.hw\"\n" "$id.hw.text tag configure big -font {Arial 10 bold}\n" "$id.hw.text configure -font {Arial 8 bold}\n" "$id.hw.text insert end \"" "The flext attribute editor lets you query or change attribute values exposed by an external object. \" big \"\n\n" "Local variable names ($-values) will only be saved as such for init values. " "Alternatively, # can be used instead of $.\n" "Ctrl-Button on a text field will open an editor window where text can be entered more comfortably.\n" "\"\n" "$id.hw.text configure -state disabled\n" "}\n") ); sys_vgui(const_cast( "proc flext_copyval {dst src} {\n" "global $src $dst\n" "set $dst [expr $$src]\n" "}\n" "proc flext_textcopy {id idtxt var} {\n" "global $var\n" "set txt [eval $idtxt get 0.0 end]\n" // strip newline characters "set tmp {}\n" "foreach t $txt { lappend tmp [string trim $t] }\n" "set $var $tmp\n" "destroy $id\n" "}\n") ); sys_vgui(const_cast( "proc flext_textzoom {id var title attr edit} {\n" "global $var\n" "toplevel $id.w\n" "wm title $id.w [concat $title \" @\" $attr]\n" // "wm iconname $w \"text\"\n" // "positionWindow $id.w\n" "frame $id.w.buttons\n" "pack $id.w.buttons -side bottom -fill x -pady 2m\n" "text $id.w.text -relief sunken -bd 2 -yscrollcommand \"$id.w.scroll set\" -setgrid 1 -width 80 -height 20\n" "scrollbar $id.w.scroll -command \"$id.w.text yview\"\n" "pack $id.w.scroll -side right -fill y\n" "pack $id.w.text -expand yes -fill both\n" // insert text with newlines "set txt [split [expr $$var] ,]\n" "set lines [llength $txt]\n" "for {set ix 0} {$ix < ($lines-1)} {incr ix} {\n" "$id.w.text insert end [string trim [lindex $txt $ix] ]\n" "$id.w.text insert end \" ,\\n\"\n" "}\n" "$id.w.text insert end [string trim [lindex $txt end] ]\n" "$id.w.text mark set insert 0.0\n" "if { $edit != 0 } then {\n" "button $id.w.buttons.ok -text OK -command \"flext_textcopy $id.w $id.w.text $var\"\n" "pack $id.w.buttons.ok -side left -expand 1\n" // "bind $id.w {} \"flext_textcopy $id.w $id.w.text $var\"\n" "} " "else { $id.w.text configure -state disabled }\n" "button $id.w.buttons.cancel -text Cancel -command \"destroy $id.w\"\n" "pack $id.w.buttons.cancel -side left -expand 1\n" "bind $id.w {} \"destroy $id.w\"\n" "}\n") ); sys_vgui(const_cast( "proc pdtk_flext_dialog {id title attrlist} {\n" "set vid [string trimleft $id .]\n" "set alen [expr [llength $attrlist] / 6 ]\n" "toplevel $id\n" "wm title $id $title\n" "wm protocol $id WM_DELETE_WINDOW [concat flext_cancel $id]\n" "frame $id.frame\n" "set row 0\n" // set grow parameters "grid columnconfigure $id.frame 0 -weight 1\n" // label "grid columnconfigure $id.frame {1 4} -weight 3\n" // value entry "grid columnconfigure $id.frame {2 3} -weight 0\n" // copy buttons "grid columnconfigure $id.frame 5 -weight 1\n" // apply button "grid columnconfigure $id.frame {6 7 8} -weight 0\n" // radio buttons "grid rowconfigure $id.frame {0 1} -weight 0\n" // set column labels "label $id.frame.label -text {attribute} -font {Helvetica 9 bold}\n" "label $id.frame.init -text {initial value} -font {Helvetica 9 bold}\n" "label $id.frame.copy -text {copy} -font {Helvetica 9 bold}\n" "label $id.frame.val -text {current value} -font {Helvetica 9 bold}\n" "label $id.frame.apply -text {} -font {Helvetica 9 bold}\n" // why must this be empty? "foreach {i txt} {0 {don't\rsave} 1 {do\rinit} 2 {always\rsave} } {\n" "label $id.frame.b$i -text $txt -font {Helvetica 7 bold}\n" "}\n" "grid config $id.frame.label -column 0 -row $row \n" "grid config $id.frame.init -column 1 -row $row \n" "grid config $id.frame.copy -column 2 -columnspan 2 -row $row \n" "grid config $id.frame.val -column 4 -row $row \n" "grid config $id.frame.apply -column 5 -row $row \n" "foreach i {0 1 2} { grid config $id.frame.b$i -column [expr $i + 6] -row $row }\n" "incr row\n" // Separator "frame $id.frame.sep -relief ridge -bd 1 -height 2\n" "grid config $id.frame.sep -column 0 -columnspan 9 -row $row -pady 2 -sticky {snew}\n" "incr row\n") ); sys_vgui(const_cast( "set ix 1\n" "foreach {an av ai atp asv afl} $attrlist {\n" "grid rowconfigure $id.frame $row -weight 1\n" // get attribute name "set var_attr_name [concat [concat var_name_$ix]_$vid ]\n" "global $var_attr_name\n" "set $var_attr_name $an\n" // get attribute init value (list) "set var_attr_init [concat [concat var_init_$ix]_$vid ]\n" "global $var_attr_init\n" "set $var_attr_init $ai\n" // get attribute value (list) "set var_attr_val [concat [concat var_val_$ix]_$vid ]\n" "global $var_attr_val\n" "set $var_attr_val $av\n" // get save flag "set var_attr_save [concat [concat var_save_$ix]_$vid ]\n" "global $var_attr_save\n" "set $var_attr_save $asv\n" // get type flag "set var_attr_type [concat [concat var_type_$ix]_$vid ]\n" "global $var_attr_type\n" "set $var_attr_type $afl\n" // add dialog elements to window // attribute label "label $id.frame.label-$ix -text \"$an :\" -font {Helvetica 8 bold}\n" "grid config $id.frame.label-$ix -column 0 -row $row -padx 5 -sticky {e}\n") ); sys_vgui(const_cast( "if { $afl != 0 } {\n" // attribute is puttable // entry field for initial value // entry field for current value // choose entry field type "switch $atp {\n" "0 - 1 {\n" // int or float "entry $id.frame.init-$ix -textvariable $var_attr_init" ST_DISABLED "\n" "entry $id.frame.val-$ix -textvariable $var_attr_val\n" "}\n" "2 {\n" // boolean "checkbutton $id.frame.init-$ix -variable $var_attr_init" ST_DISABLED "\n" "checkbutton $id.frame.val-$ix -variable $var_attr_val\n" "}\n" "3 {\n" // symbol "entry $id.frame.init-$ix -textvariable $var_attr_init" ST_DISABLED "\n" "entry $id.frame.val-$ix -textvariable $var_attr_val\n" "}\n" "4 - 5 {\n" // list or unknown "entry $id.frame.init-$ix -textvariable $var_attr_init" ST_DISABLED "\n" "bind $id.frame.init-$ix {} \" flext_textzoom $id.frame.init-$ix $var_attr_init { $title } $an 1\"\n" "entry $id.frame.val-$ix -textvariable $var_attr_val\n" "bind $id.frame.val-$ix {} \" flext_textzoom $id.frame.val-$ix $var_attr_val { $title } $an 1\"\n" "}\n" "}\n" "grid config $id.frame.init-$ix -column 1 -row $row -padx 5 -sticky {ew}\n" "grid config $id.frame.val-$ix -column 4 -row $row -padx 5 -sticky {ew}\n" // copy buttons "button $id.frame.b2i-$ix -text {<-} -height 1 -command \" flext_copyval $var_attr_init $var_attr_val \"" ST_DISABLED "\n" "grid config $id.frame.b2i-$ix -column 2 -row $row -sticky {ew}\n" "button $id.frame.b2c-$ix -text {->} -height 1 -command \" flext_copyval $var_attr_val $var_attr_init \"\n" "grid config $id.frame.b2c-$ix -column 3 -row $row -sticky {ew}\n" // apply button "button $id.frame.apply-$ix -text {Apply} -height 1 -command \" flext_apply $id $ix \"\n" "grid config $id.frame.apply-$ix -column 5 -row $row -sticky {ew}\n" // radiobuttons "foreach {i c} {0 black 1 blue 2 red} {\n" "radiobutton $id.frame.b$i-$ix -value $i -foreground $c -variable $var_attr_save" ST_DISABLED "\n" "grid config $id.frame.b$i-$ix -column [expr $i + 6] -row $row\n" "}\n") ); sys_vgui(const_cast( "} else {\n" // attribute is gettable only // entry field for current value (read-only) // choose display field type "switch $atp {\n" "0 - 1 {\n" // int or float "entry $id.frame.val-$ix -textvariable $var_attr_val -state disabled\n" "}\n" "2 {\n" // boolean "checkbutton $id.frame.val-$ix -variable $var_attr_val -state disabled\n" "}\n" "3 {\n" // symbol "entry $id.frame.val-$ix -textvariable $var_attr_val -state disabled\n" "}\n" "4 - 5 {\n" // list or unknown "entry $id.frame.val-$ix -textvariable $var_attr_val -state disabled\n" "bind $id.frame.val-$ix {} \" flext_textzoom $id.frame.val-$ix $var_attr_val { $title } $an 0\"\n" "}\n" "}\n" // "entry $id.fval.val-$ix -textvariable $var_attr_val -state disabled\n" "grid config $id.frame.val-$ix -column 4 -row $row -padx 5 -sticky {ew}\n" "label $id.frame.readonly-$ix -text \"read-only\"\n" "grid config $id.frame.readonly-$ix -column 6 -columnspan 3 -row $row -padx 5 -sticky {ew}\n" "}\n" // increase counter "incr ix\n" "incr row\n" "}\n" // empty space "grid rowconfigure $id.frame $row -weight 1\n" "frame $id.frame.dummy\n" "grid config $id.frame.dummy -column 0 -columnspan 9 -row $row\n" "incr row\n") ); sys_vgui(const_cast( // Separator "frame $id.sep2 -relief ridge -bd 1 -height 2\n" // Buttons "frame $id.buttonframe\n" "button $id.buttonframe.cancel -text {Leave} -width 20 -command \" flext_cancel $id \"\n" "button $id.buttonframe.apply -text {Apply all} -width 20 -command \" flext_applyall $id $alen \"\n" "button $id.buttonframe.ok -text {Apply & Leave} -width 20 -command \" flext_ok $id $alen \"\n" "button $id.buttonframe.help -text {Help} -width 10 -command \" flext_help $id \"\n" "grid columnconfigure $id.buttonframe {0 1 2 3} -weight 1\n" "grid config $id.buttonframe.cancel $id.buttonframe.apply $id.buttonframe.ok $id.buttonframe.help -padx 2 -sticky {snew}\n" // "scrollbar $id.scroll -command \"$id.frame yview\"\n" "pack $id.buttonframe $id.sep2 -pady 2 -expand 0 -side bottom -fill x\n" // "pack $id.scroll -side right -fill y\n" "pack $id.frame -expand 1 -side top -fill both\n" // Key bindings "bind $id {} \" flext_cancel $id \"\n" "bind $id {} \" flext_ok $id $alen \"\n" "bind $id {} \" flext_applyall $id $alen \"\n" "}\n") ); } #endif #ifdef __FLEXT_WIDGETBEHAVIOR static t_widgetbehavior widgetbehavior; #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::SetGfx(t_classid c) { t_class *cl = getClass(c); // widgetbehavior struct MUST be resident... (static is just ok here) #ifdef __FLEXT_WIDGETBEHAVIOR #ifndef __FLEXT_CLONEWIDGET widgetbehavior.w_visfn = cl->c_wb->w_visfn; widgetbehavior.w_selectfn = cl->c_wb->w_selectfn; widgetbehavior.w_getrectfn = cl->c_wb->w_getrectfn; widgetbehavior.w_displacefn = cl->c_wb->w_displacefn; widgetbehavior.w_activatefn = cl->c_wb->w_activatefn; widgetbehavior.w_deletefn = cl->c_wb->w_deletefn; widgetbehavior.w_selectfn = cl->c_wb->w_selectfn; widgetbehavior.w_clickfn = cl->c_wb->w_clickfn; #else widgetbehavior.w_visfn = text_widgetbehavior.w_visfn; widgetbehavior.w_selectfn = text_widgetbehavior.w_selectfn; widgetbehavior.w_getrectfn = text_widgetbehavior.w_getrectfn; widgetbehavior.w_displacefn = text_widgetbehavior.w_displacefn; widgetbehavior.w_activatefn = text_widgetbehavior.w_activatefn; widgetbehavior.w_deletefn = text_widgetbehavior.w_deletefn; widgetbehavior.w_selectfn = text_widgetbehavior.w_selectfn; widgetbehavior.w_clickfn = text_widgetbehavior.w_clickfn; #endif #endif #ifdef FLEXT_ATTRHIDE #ifndef __FLEXT_CLONEWIDGET ori_vis = widgetbehavior.w_visfn; ori_select = widgetbehavior.w_selectfn; #endif widgetbehavior.w_visfn = (t_visfn)cb_GfxVis; widgetbehavior.w_selectfn = (t_selectfn)cb_GfxSelect; #if PD_MINOR_VERSION >= 37 class_setsavefn(cl,(t_savefn)cb_GfxSave); #else widgetbehavior.w_savefn = (t_savefn)cb_GfxSave; #endif #endif // FLEXT_ATTRHIDE #ifndef FLEXT_NOATTREDIT #if PD_MINOR_VERSION >= 37 class_setpropertiesfn(cl,(t_propertiesfn)cb_GfxProperties); #else widgetbehavior.w_propertiesfn = (t_propertiesfn)cb_GfxProperties; #endif FLEXT_TEMPINST(tclscript)(); #endif // FLEXT_NOATTREDIT #ifdef __FLEXT_WIDGETBEHAVIOR class_setwidget(cl, &widgetbehavior); #endif } #ifndef FLEXT_NOATTREDIT FLEXT_TEMPLATE size_t escapeit(char *dst,size_t maxlen,const char *src) { char *d; for(d = dst; *src && (d-dst) < (int)maxlen; ++src) { if(*src == '%') { *(d++) = '%'; *(d++) = '%'; } else *(d++) = *src; } *d = 0; return d-dst; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_GfxProperties(flext_hdr *c, t_glist *) { flext_base *th = thisObject(c); char buf[1000]; // beginning of proc sys_vgui(const_cast("proc pdtk_flext_dialog_%p {title} {\n"),th); sys_vgui(const_cast("pdtk_flext_dialog $title {\n")); // add title t_text *x = (t_text *)c; FLEXT_ASSERT(x->te_binbuf); int argc = binbuf_getnatom(x->te_binbuf); t_atom *argv = binbuf_getvec(x->te_binbuf); PrintList(argc,argv,buf,sizeof(buf)); sys_vgui(const_cast("%s } {\n"),buf); AtomListStatic<32> la; th->ListAttrib(la); int cnt = la.Count(); for(int i = 0; i < cnt; ++i) { const t_symbol *sym = GetSymbol(la[i]); // get attribute AttrItem *gattr = th->FindAttrib(sym,true); // get puttable attribute AttrItem *pattr = gattr?gattr->Counterpart():th->FindAttrib(sym,false); // get flags int sv; const AtomList *initdata; const AttrData *a = th->attrdata->find(sym); // AttrDataCont::iterator it = th->attrdata->find(sym); // if(it == th->attrdata->end()) if(!a) { sv = 0; initdata = NULL; } else { // const AttrData &a = *it.data(); if(a->IsSaved()) sv = 2; else if(a->IsInit()) sv = 1; else sv = 0; initdata = a->IsInitValue()?&a->GetInitValue():NULL; } // get attribute type int tp; bool list; switch((gattr?gattr:pattr)->argtp) { case a_int: tp = 0; list = false; break; case a_float: tp = 1; list = false; break; case a_bool: tp = 2; list = false; break; case a_symbol: tp = 3; list = true; break; case a_list: case a_LIST: tp = 4; list = true; break; default: tp = 5; list = true; FLEXT_ASSERT(false); } sys_vgui(const_cast(list?"%s {":"%s "),GetString(sym)); AtomListStatic<32> lv; if(gattr) { // gettable attribute is present // Retrieve attribute value th->GetAttrib(sym,gattr,lv); char *b = buf; *b = 0; for(int j = 0; j < lv.Count(); ++j) { char tmp[100]; PrintAtom(lv[j],tmp,sizeof tmp); b += FLEXT_TEMPINST(escapeit)(b,sizeof(buf)+buf-b,tmp); if(j < lv.Count()-1) { *(b++) = ' '; *b = 0; } } sys_vgui(const_cast("%s"),buf); } else sys_vgui(const_cast("{}")); sys_vgui(const_cast(list?"} {":" ")); if(pattr) { // if there is initialization data take this, otherwise take the current data const AtomList &lp = initdata?*initdata:static_cast(lv); char *b = buf; *b = 0; for(int j = 0; j < lp.Count(); ++j) { char tmp[256]; PrintAtom(lp[j],tmp,sizeof(tmp)); b += FLEXT_TEMPINST(escapeit)(b,sizeof(buf)+buf-b,tmp); if(j < lp.Count()-1) { *(b++) = ' '; *b = 0; } } sys_vgui(const_cast("%s"),buf); } else sys_vgui(const_cast("{}")); sys_vgui(const_cast(list?"} %i %i %i \n":" %i %i %i \n"),tp,sv,pattr?(pattr->BothExist()?2:1):0); } sys_vgui(const_cast(" } }\n")); // end of proc STD::sprintf(buf,"pdtk_flext_dialog_%p %%s\n",th); gfxstub_new((t_pd *)th->thisHdr(), th->thisHdr(),buf); //! \todo delete proc in TCL space } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::cb_AttrDialog(flext_base *th,int argc,const t_atom *argv) { for(int i = 0; i < argc; ) { FLEXT_ASSERT(IsSymbol(argv[i])); // get name const t_symbol *aname = GetSymbol(argv[i]); i++; // get current value FLEXT_ASSERT(CanbeInt(argv[i])); int ccnt,coffs; ccnt = GetAInt(argv[i]); coffs = ++i; i += ccnt; // get init value FLEXT_ASSERT(CanbeInt(argv[i])); int icnt,ioffs; icnt = GetAInt(argv[i]); ioffs = ++i; i += icnt; FLEXT_ASSERT(i < argc); int sv = GetAInt(argv[i]); ++i; // find puttable attribute AttrItem *attr = th->FindAttrib(aname,false); if(attr) { bool ret = th->SetAttrib(aname,attr,ccnt,argv+coffs); FLEXT_ASSERT(ret); AttrData *a = th->attrdata->find(aname); if(sv >= 1) { // if data not present create it if(!a) { AttrData *old = th->attrdata->insert(aname,a = new AttrData); FLEXT_ASSERT(!old); } a->SetSave(sv == 2); a->SetInit(true); a->SetInitValue(icnt,argv+ioffs); } else { if(a) { // if data is present reset flags a->SetSave(false); a->SetInit(false); // let init data as is } } } else { post("%s - Attribute %s can't be set",th->thisName(),GetString(aname)); } } return true; } #endif // FLEXT_NOATTREDIT #ifdef FLEXT_ATTRHIDE template void BinbufAdd(t_binbuf *b,const t_atom &at,bool transdoll) { if(transdoll && at.a_type == A_DOLLAR) { char tbuf[MAXPDSTRING]; sprintf(tbuf, "$%d", at.a_w.w_index); binbuf_addv(b,"s",flext::MakeSymbol(tbuf)); } else if(transdoll && at.a_type == A_DOLLSYM) { char tbuf[MAXPDSTRING]; sprintf(tbuf, "$%s", at.a_w.w_symbol->s_name); binbuf_addv(b,"s",flext::MakeSymbol(tbuf)); } else binbuf_add(b,1,const_cast(&at)); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::BinbufArgs(t_binbuf *b,t_binbuf *args,bool withname,bool transdoll) { int argc = binbuf_getnatom(args); t_atom *argv = binbuf_getvec(args); int i,cnt = CheckAttrib(argc,argv); // process the creation arguments for(i = withname?0:1; i < cnt; ++i) BinbufAdd(b,argv[i],transdoll); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::BinbufAttr(t_binbuf *b,bool transdoll) { // process the attributes AtomListStatic<32> la,lv; ListAttrib(la); int i,cnt = la.Count(); for(i = 0; i < cnt; ++i) { const t_symbol *sym = GetSymbol(la[i]); const AtomList *lref = NULL; AttrData *a = attrdata->find(sym); if(a) { if(a->IsInit() && a->IsInitValue()) { lref = &a->GetInitValue(); #if 0 ///////////////////////////////////////////////////////////// // check for $-parameters lv = lref->Count(); for(int j = 0; j < lref->Count(); ++j) { const char *s = IsSymbol((*lref)[j])?GetString((*lref)[j]):NULL; if(s && s[0] == '$') { // TODO: More refined checking? // prepend a "\" char tmp[256]; *tmp = '\\'; strcpy(tmp+1,s); SetString(lv[j],tmp); } else lv[i] = (*lref)[j]; } lref = &lv; #endif ///////////////////////////////////////////////////////////// } // else if(a.IsSaved()) { else if(a->IsSaved()) { AttrItem *attr = FindAttrib(sym,true); // attribute must be gettable (so that the data can be retrieved) and puttable (so that the data can be inited) if(attr && attr->BothExist()) { GetAttrib(sym,attr,lv); lref = &lv; } } } if(lref) { char attrname[256]; *attrname= '@'; // store name strcpy(attrname+1,GetString(sym)); binbuf_addv(b,"s",MakeSymbol(attrname)); // store value for(int j = 0; j < lref->Count(); ++j) BinbufAdd(b,(*lref)[j],transdoll); } } } //! Strip the attributes off the object command line FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_GfxVis(flext_hdr *c, t_glist *gl, int vis) { if(!gl->gl_isgraph || gl->gl_havewindow) { // show object if it's not inside a GOP flext_base *th = thisObject(c); t_text *x = (t_text *)c; FLEXT_ASSERT(x->te_binbuf); t_binbuf *b = binbuf_new(); th->BinbufArgs(b,x->te_binbuf,true,false); // delete old object box text binbuf_free(x->te_binbuf); // set new one x->te_binbuf = b; t_rtext *rt = glist_findrtext(gl,x); rtext_retext(rt); // now display the changed text with the normal drawing function #ifdef __FLEXT_CLONEWIDGET text_widgetbehavior.w_visfn((t_gobj *)c,gl,vis); #else ori_vis((t_gobj *)c,gl,vis); #endif } // else don't show } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_GfxSelect(flext_hdr *c,t_glist *gl,int state) { t_text *x = (t_text *)c; flext_base *th = thisObject(c); if(!gl->gl_isgraph || gl->gl_havewindow) { if(state || !gl->gl_editor->e_textdirty) { // change text only on selection // OR if text has _not_ been changed // -> since object will not be recreated we have to get rid // of the attribute text FLEXT_ASSERT(x->te_binbuf); t_binbuf *b = binbuf_new(); th->BinbufArgs(b,x->te_binbuf,true,false); if(state) th->BinbufAttr(b,false); // delete old object box text binbuf_free(x->te_binbuf); // set new one x->te_binbuf = b; t_rtext *rt = glist_findrtext(gl,x); rtext_retext(rt); // fix lines canvas_fixlinesfor(gl,x); } // call original function #ifdef __FLEXT_CLONEWIDGET text_widgetbehavior.w_selectfn((t_gobj *)c,gl,state); #else ori_select((t_gobj *)c,gl,state); #endif } } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_GfxSave(flext_hdr *c, t_binbuf *b) { flext_base *th = thisObject(c); t_text *t = (t_text *)c; binbuf_addv(b, "ssiis", gensym("#X"),gensym("obj"), t->te_xpix, t->te_ypix,MakeSymbol(th->thisName())); // process the object arguments th->BinbufArgs(b,t->te_binbuf,false,true); // process the attributes th->BinbufAttr(b,true); // add end sign binbuf_addv(b, ";"); } #endif // FLEXT_ATTRHIDE #endif // FLEXT_SYS_PD #include "flpopns.h" #endif // __FLEXT_ATTR_ED_CPP flext-0-6-3/source/flbase.cpp000066400000000000000000000134151446466241400161170ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flbase.cpp \brief Implementation of the internal flext base classes. \remark This is all derived from GEM by Mark Danks */ #ifndef __FLEXT_BASE_CPP #define __FLEXT_BASE_CPP #include "flext.h" #include "flinternal.h" #include #include #include #if FLEXT_SYS == FLEXT_SYS_PD #ifdef _MSC_VER #pragma warning (push) #pragma warning (disable:4091) #endif // for canvas_realizedollar (should be non-critical) #include #ifdef _MSC_VER #pragma warning (pop) #endif #endif #include "flpushns.h" ///////////////////////////////////////////////////////// // // flext_obj // ///////////////////////////////////////////////////////// FLEXT_TEMPIMPL(flext_hdr *FLEXT_CLASSDEF(flext_obj))::m_holder = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext_obj))::m_holdname = NULL; FLEXT_TEMPIMPL(FLEXT_TEMPINST(flext_class) *FLEXT_CLASSDEF(flext_obj))::m_holdclass = NULL; FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext_obj))::m_holdaargc = 0; FLEXT_TEMPIMPL(const t_atom *FLEXT_CLASSDEF(flext_obj))::m_holdaargv = NULL; //FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::process_attributes = false; FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::initing = false; FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::exiting = false; FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::init_ok; //FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::ProcessAttributes(bool attr) { process_attributes = attr; } #if FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext_obj))::sym__shP = NULL; #endif ///////////////////////////////////////////////////////// // Constructor // ///////////////////////////////////////////////////////// FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_obj))::FLEXT_CLASSDEF(flext_obj)() : x_obj(m_holder) , clss(m_holdclass) , m_name(m_holdname) { #if FLEXT_SYS == FLEXT_SYS_PD m_canvas = canvas_getcurrent(); #elif FLEXT_SYS == FLEXT_SYS_MAX m_canvas = (t_patcher *)sym__shP->s_thing; x_obj->curinlet = 0; #endif } ///////////////////////////////////////////////////////// // Destructor // ///////////////////////////////////////////////////////// FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_obj))::~FLEXT_CLASSDEF(flext_obj)() { x_obj = NULL; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::__setup__(t_classid) { #if FLEXT_SYS == FLEXT_SYS_MAX sym__shP = MakeSymbol("#P"); #endif flext::Setup(); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::Init() { return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::Finalize() { return true; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::Exit() {} FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::DefineHelp(t_classid c,const char *ref,const char *dir,bool addtilde) { #if FLEXT_SYS == FLEXT_SYS_PD char tmp[256]; if(dir && *dir) { strcpy(tmp,dir); char *last = tmp+strlen(tmp)-1; if(*last != '/') strcat(last,"/"); strcat(last,ref); } else strcpy(tmp,ref); if(addtilde) strcat(tmp,"~"); ::class_sethelpsymbol(getClass(c),gensym(const_cast(tmp))); #else // no solution for Max/MSP yet #endif } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::GetParamSym(t_atom &dst,const t_symbol *sym,t_canvas *c) { #if FLEXT_SYS == FLEXT_SYS_PD && defined(PD_MINOR_VERSION) && PD_MINOR_VERSION >= 37 if(!c) c = canvas_getcurrent(); const char *s = GetString(sym); if((s[0] == '$' || s[0] == '#') && isdigit(s[1])) { const t_symbol *res; // patcher parameter detected... get value! if(s[0] != '$') { char tmp[MAXPDSTRING]; strcpy(tmp,s); tmp[0] = '$'; res = canvas_realizedollar(c,const_cast(MakeSymbol(tmp))); } else res = canvas_realizedollar(c,const_cast(sym)); // check for number const char *cn = GetString(res); while(*cn && (isdigit(*cn) || *cn == '.')) ++cn; if(!*cn) SetFloat(dst,(float)atof(GetString(res))); else SetSymbol(dst,res); return true; } else #else // #pragma message("Not implemented") #endif SetSymbol(dst,sym); return true; } #if FLEXT_SYS == FLEXT_SYS_PD // this declaration is missing in m_pd.h (0.37-0 and -1) // but it is there in 0.37-2 (but how to tell which micro-version?) extern "C" #ifdef _MSC_VER __declspec(dllimport) #endif void canvas_getargs(int *argcp, t_atom **argvp); #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::GetCanvasArgs(AtomList &args) const { #if FLEXT_SYS == FLEXT_SYS_PD int argc; t_atom *argv; canvas_getargs(&argc,&argv); args(argc,argv); #else // #pragma message("Not implemented") args(0); #endif } #if FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPLATE short patcher_myvol(t_patcher *x) { #ifndef MM_UNIFIED // Max5 check... we don't know what to do yet t_box *w; if(x->p_vol) return x->p_vol; else if((w = (t_box *)x->p_vnewobj) != NULL) return FLEXT_TEMPINST(patcher_myvol)(w->b_patcher); else #endif return 0; } #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::GetCanvasDir(char *buf,size_t bufsz) const { #if FLEXT_SYS == FLEXT_SYS_PD const char *c = GetString(canvas_getdir(thisCanvas())); strncpy(buf,c,bufsz); #elif FLEXT_SYS == FLEXT_SYS_MAX short path = FLEXT_TEMPINST(patcher_myvol)(thisCanvas()); // \TODO dangerous!! no check for path length (got to be long enough... like 1024 chars) path_topathname(path,NULL,buf); #else #error Not implemented #endif } #include "flpopns.h" #endif // __FLEXT_BASE_CPP flext-0-6-3/source/flbase.h000066400000000000000000000477571446466241400156040ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flbase.h \brief Internal flext base classes \remark This uses some ideas of GEM invented by Mark Danks */ #ifndef __FLEXT_BASE_H #define __FLEXT_BASE_H #include "flstdc.h" #include "flsupport.h" #include #include "flpushns.h" FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_obj); typedef FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_obj)) flext_obj; // ---------------------------------------------------------------------------- /*! \brief The obligatory PD or Max/MSP object header \internal This is in a separate struct to assure that obj is the very first thing. If it were the first thing in flext_obj, then there could be problems with the virtual table of the C++ class. */ // ---------------------------------------------------------------------------- struct FLEXT_SHARE flext_hdr { /*! \defgroup FLEXT_OBJHEADER Actual PD or Max/MSP object \internal @{ */ /*! \brief The obligatory object header \note MUST reside at memory offset 0 (no virtual table possible) */ t_sigobj obj; #if FLEXT_SYS == FLEXT_SYS_PD //! PD only: float signal holder for pd float defsig; #endif #if FLEXT_SYS == FLEXT_SYS_MAX //! Max/MSP only: current inlet used by proxy objects long curinlet; #endif /*! \brief This points to the actual polymorphic C++ class */ FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_obj)) *data; //! @} FLEXT_OBJHEADER }; FLEXT_TEMPLATE class flext_class; typedef std::map LibMap; class flext_library; // ---------------------------------------------------------------------------- /*! \brief The mother of base classes for all flext external objects Each extern which is written in C++ needs to use the #defines at the end of this header file. The define FLEXT_HEADER(NEW_CLASS, PARENT_CLASS) should be somewhere in your header file. One of the defines like FLEXT_NEW(NEW_CLASS) or FLEXT_NEW_2(NEW_CLASS, float, float) should be the first thing in your implementation file. NEW_CLASS is the name of your class and PARENT_CLASS is the parent of your class. */ // ---------------------------------------------------------------------------- FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_obj): public flext { public: // --- creation ------------------------------------------------------- /*! \defgroup FLEXT_OBJ_CREATION Object creation/destruction functionality @{ */ //! Constructor FLEXT_CLASSDEF(flext_obj)(); //! Destructor virtual ~FLEXT_CLASSDEF(flext_obj)(); /*! \brief Signal a construction problem \note This should only be used in the constructor. Object creation will be aborted. */ static void InitProblem() { init_ok = false; } /*! \brief Enable/disable attribute procession (default = false) \note Use that in the static class setup function (also library setup function) */ // static void ProcessAttributes(bool attr); //{ process_attributes = attr; } //! Virtual function called at creation time (but after the constructor) // this also guarantees that there are no instances of flext_obj virtual bool Init(); //! Virtual function called after Init() has succeeded virtual bool Finalize(); //! Virtual function called at destruction (before the destructor) virtual void Exit(); //! @} FLEXT_OBJ_CREATION // --- info ------------------------------------------------------- /*! \defgroup FLEXT_OBJ_INFO Get various information @{ */ //! Get the object's canvas t_canvas *thisCanvas() const { return m_canvas; } //! Get the PD or Max/MSP object t_sigobj *thisHdr() { FLEXT_ASSERT(x_obj); return &x_obj->obj; } const t_sigobj *thisHdr() const { FLEXT_ASSERT(x_obj); return &x_obj->obj; } //! Get the class name (as a string) const char *thisName() const { return GetString(m_name); } //! Get the class name (as a symbol) const t_symbol *thisNameSym() const { return m_name; } //! Get the class pointer t_class *thisClass() const; //! Typedef for unique class identifier typedef FLEXT_TEMPINST(flext_class) *t_classid; //! Get unique id for object class t_classid thisClassId() const { return clss; } //! Get class pointer from class id static t_class *getClass(t_classid id); static bool HasAttributes(t_classid id); static bool IsDSP(t_classid id); static bool HasDSPIn(t_classid id); static bool IsLib(t_classid id); bool HasAttributes() const; bool IsLib() const; bool IsDSP() const; bool HasDSPIn() const; #if FLEXT_SYS == FLEXT_SYS_MAX // under Max/MSP it could be necessary to activate DSP also for message objects // namely for those coexisting with DSP objects in a library bool NeedDSP() const; #endif //! @} FLEXT_OBJ_INFO // --- help ------------------------------------------------------- /*! \defgroup FLEXT_OBJ_HELP Help/assistance functionality \remark This is still PD only @{ */ /*! Define the help reference symbol for a class \internal */ static void DefineHelp(t_classid c,const char *ref,const char *dir = NULL,bool addtilde = false); //! Define the help reference symbol for a class void DefineHelp(const char *ref,const char *dir = NULL,bool addtilde = false) { DefineHelp(thisClassId(),ref,dir,addtilde); } //! @} FLEXT_OBJ_HELP // --- internal stuff ------------------------------------------------------- /*! \defgroup FLEXT_OBJ_INTERNAL Internal stuff \internal @{ */ protected: //! backpointer to object header mutable flext_hdr *x_obj; //! pointer to flext class definition FLEXT_TEMPINST(flext_class) *clss; // static bool process_attributes; #if FLEXT_SYS == FLEXT_SYS_MAX t_critical lock; void Lock() { critical_enter(lock); } void Unlock() { critical_exit(lock); } static void SysLock() { critical_enter(0); } static void SysUnlock() { critical_exit(0); } #elif FLEXT_SYS == FLEXT_SYS_PD void Lock() {} void Unlock() {} static void SysLock() {} static void SysUnlock() {} #else #error #endif class Locker { public: Locker(flext_obj *o = NULL): obj(o) { if(obj) obj->Lock(); else SysLock(); } Locker(flext_hdr *h): obj(h->data) { FLEXT_ASSERT(obj); obj->Lock(); } ~Locker() { if(obj) obj->Unlock(); else SysUnlock(); } protected: flext_obj *obj; }; private: //! The canvas (patcher) that the object is in mutable t_canvas *m_canvas; //! Flag for successful object construction static bool init_ok; // flags for init and exit procedure; static bool initing; static bool exiting; public: //! Creation callback static void __setup__(t_classid); /*! \brief This is a temporary holder \warning don't touch it! */ static flext_hdr *m_holder; //! Hold object's class during construction static FLEXT_TEMPINST(flext_class) *m_holdclass; //! Hold object's name during construction static const t_symbol *m_holdname; //! Holders for attribute procession flag static int m_holdaargc; static const t_atom *m_holdaargv; /*! The object's name in the patcher \note objects of the same class can have various alias names! */ const t_symbol *m_name; /*! Return true if in object initialization phase true when in constructor or Init, false when in Finalize */ static bool Initing() { return initing; } //! Return true if in object destruction phase (Exit or destructor) static bool Exiting() { return exiting; } // Definitions for library objects static void lib_init(const char *name,void setupfun()); static void obj_add(bool lib,bool dsp,bool noi,bool attr,const char *idname,const char *names,void setupfun(t_classid),FLEXT_CLASSDEF(flext_obj) *(*newfun)(int,t_atom *),void (*freefun)(flext_hdr *),int argtp1,...); #if FLEXT_SYS == FLEXT_SYS_MAX static flext_hdr *obj_new(const t_symbol *s,short argc,t_atom *argv); #else static flext_hdr *obj_new(const t_symbol *s,int argc,t_atom *argv); #endif static void obj_free(flext_hdr *o); //! Convert $0 or #0 symbol into appropriate value static bool GetParamSym(t_atom &dst,const t_symbol *s,t_canvas *c); //! Get the canvas arguments void GetCanvasArgs(AtomList &args) const; //! Get the canvas/patcher directory void GetCanvasDir(char *buf,size_t bufsz) const; protected: // Current library class static flext_library *curlib; // static initialization (with constructor) doesn't work for Codewarrior static LibMap *libnames; static FLEXT_TEMPINST(flext_class) *FindName(const t_symbol *s,FLEXT_TEMPINST(flext_class) *o = NULL); #if FLEXT_SYS == FLEXT_SYS_PD static t_class *buf_class; static void cb_buffer_dsp(void *c,t_signal **sp); #endif #if FLEXT_SYS == FLEXT_SYS_MAX static const t_symbol *sym__shP; #endif //! @} FLEXT_OBJ_INTERNAL }; // max. 4 creation args (see the following macros) #define FLEXT_MAXNEWARGS 4 // max. 5 method args (see the following macros) #define FLEXT_MAXMETHARGS 5 // prefixes for the macro generated handler functions #define FLEXT_CALL_PRE(F) flext_c_##F #define FLEXT_THR_PRE(F) flext_t_##F #define FLEXT_GET_PRE(F) flext_g_##F #define FLEXT_SET_PRE(F) flext_s_##F #ifndef FLEXT_ATTRIBUTES /*! \brief Switch for global attribute processing \note Should be set to 1 or 0 (or not be defined) \ingroup FLEXT_DEFS */ #define FLEXT_ATTRIBUTES \ \ 0 #elif FLEXT_ATTRIBUTES != 0 && FLEXT_ATTRIBUTES != 1 #error "FLEXT_ATTRIBUTES must be 0 or 1" #endif // ---------------------------------------- // These should be used in the header // ---------------------------------------- #define FLEXT_REALHDR(NEW_CLASS, PARENT_CLASS) \ public: \ typedef NEW_CLASS thisType; \ typedef PARENT_CLASS thisParent; \ static FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_obj)) *__init__(int argc,t_atom *argv); \ static void __free__(flext_hdr *hdr) { delete hdr->data; } \ static void __setup__(flext_obj::t_classid classid) { thisParent::__setup__(classid); } #define FLEXT_REALHDR_S(NEW_CLASS, PARENT_CLASS,SETUPFUN) \ public: \ typedef NEW_CLASS thisType; \ typedef PARENT_CLASS thisParent; \ static FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_obj)) *__init__(int argc,t_atom *argv); \ static void __free__(flext_hdr *hdr) { delete hdr->data; } \ static void __setup__(flext_obj::t_classid classid) { \ thisParent::__setup__(classid); \ thisType::SETUPFUN(classid); \ } #define FLEXT_REALHDR_T(NEW_CLASS, PARENT_CLASS) \ public: \ typedef NEW_CLASS thisType; \ typedef PARENT_CLASS thisParent; \ typedef typename thisParent::t_classid t_classid; \ static FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_obj)) *__init__(int argc,t_atom *argv); \ static void __free__(flext_hdr *hdr) { delete hdr->data; } \ static void __setup__(flext_obj::t_classid classid) { thisParent::__setup__(classid); } #define FLEXT_REALHDR_TS(NEW_CLASS, PARENT_CLASS,SETUPFUN) \ public: \ typedef NEW_CLASS thisType; \ typedef PARENT_CLASS thisParent; \ typedef typename thisParent::t_classid t_classid; \ static FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_obj)) *__init__(int argc,t_atom *argv); \ static void __free__(flext_hdr *hdr) { delete hdr->data; } \ static void __setup__(flext_obj::t_classid classid) { \ thisParent::__setup__(classid); \ thisType::SETUPFUN(classid); \ } // generate name of dsp/non-dsp setup function #if defined(FLEXT_USE_HEX_SETUP_NAME) && defined(FLEXT_SYS_PD) #define FLEXT_STPF_0(NAME) setup_##NAME #define FLEXT_STPF_1(NAME) setup_##NAME #elif FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX #define FLEXT_STPF_0(NAME) NAME##_setup #define FLEXT_STPF_1(NAME) NAME##_tilde_setup #else #error Platform not supported #endif #define FLEXT_STPF_(DSP) FLEXT_STPF_##DSP #define FLEXT_STPF(NAME,DSP) FLEXT_STPF_(DSP)(NAME) // -------------------------------------------------------------------------------------- // used in library setup functions to register the individual objects in the library #define REAL_SETUP(cl,DSP) extern void FLEXT_STPF(cl,DSP)(); FLEXT_STPF(cl,DSP)(); #ifdef FLEXT_USE_NAMESPACE #define _FLEXT_REAL_SETUP_NAME(NAME) ::##NAME##_setup #else #define _FLEXT_REAL_SETUP_NAME(NAME) NAME##_setup #endif // specify that to define the library itself #if FLEXT_SYS == FLEXT_SYS_PD # define REAL_LIB_SETUP(NAME,SETUPFUN) extern "C" FLEXT_EXT void _FLEXT_REAL_SETUP_NAME(NAME)() { flext_obj::lib_init(#NAME,SETUPFUN); } #elif FLEXT_SYS == FLEXT_SYS_MAX # define REAL_LIB_SETUP(NAME,SETUPFUN) extern "C" FLEXT_EXT int main() { flext_obj::lib_init(#NAME,SETUPFUN); return 0; } #else # error Platform not supported #endif // -------------------------------------------------- #define FLEXT_EXP_0 extern "C" FLEXT_EXT #define FLEXT_EXP_1 #define FLEXT_EXP(LIB) FLEXT_EXP_##LIB #if FLEXT_SYS == FLEXT_SYS_PD #define FLEXT_OBJ_SETUP_0(NEW_CLASS,DSP) #elif FLEXT_SYS == FLEXT_SYS_MAX #define FLEXT_OBJ_SETUP_0(NEW_CLASS,DSP) extern "C" FLEXT_EXT int main() { FLEXT_STPF(NEW_CLASS,DSP)(); return 0; } #else #error not implemented #endif #define FLEXT_OBJ_SETUP_1(NEW_CLASS,DSP) #define FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) FLEXT_OBJ_SETUP_##LIB(NEW_CLASS,DSP) // ---------------------------------------- // These definitions are used below // ---------------------------------------- #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX // maybe that's not necessary #define FLEXTTPN_NULL A_NULL #if FLEXT_SYS == FLEXT_SYS_PD #define FLEXTTPN_PTR A_POINTER #else #define FLEXTTPN_INT A_INT #define FLEXTTPN_DEFINT A_DEFINT #endif #define FLEXTTPN_FLOAT A_FLOAT #define FLEXTTPN_DEFFLOAT A_DEFFLOAT #define FLEXTTPN_SYM A_SYMBOL #define FLEXTTPN_DEFSYM A_DEFSYMBOL #define FLEXTTPN_VAR A_GIMME #else #define FLEXTTPN_NULL 0 #define FLEXTTPN_PTR 1 #define FLEXTTPN_INT 2 #define FLEXTTPN_FLOAT 3 #define FLEXTTPN_SYM 4 #define FLEXTTPN_VAR 5 #define FLEXTTPN_DEFINT 6 #define FLEXTTPN_DEFFLOAT 7 #define FLEXTTPN_DEFSYM 8 #endif // Shortcuts for PD/Max type arguments #define FLEXTTYPE_void FLEXTTPN_NULL #define CALLBTYPE_void void #define FLEXTTYPE_float FLEXTTPN_FLOAT #define FLEXTTYPE_float0 FLEXTTPN_DEFFLOAT #define CALLBTYPE_float float #define FLEXTTYPE_t_float FLEXTTPN_FLOAT #define CALLBTYPE_t_float t_float #if FLEXT_SYS == FLEXT_SYS_PD #define FLEXTTYPE_int FLEXTTPN_FLOAT #define FLEXTTYPE_int0 FLEXTTPN_DEFFLOAT #define CALLBTYPE_int float #define FLEXTTYPE_bool FLEXTTPN_FLOAT #define FLEXTTYPE_bool0 FLEXTTPN_DEFFLOAT #define CALLBTYPE_bool float #elif FLEXT_SYS == FLEXT_SYS_MAX #define FLEXTTYPE_int FLEXTTPN_INT #define FLEXTTYPE_int0 FLEXTTPN_DEFINT #define CALLBTYPE_int int #define FLEXTTYPE_bool FLEXTTPN_INT #define FLEXTTYPE_bool0 FLEXTTPN_DEFINT #define CALLBTYPE_bool int #else #error Platform not supported #endif #define FLEXTTYPE_t_symptr FLEXTTPN_SYM #define FLEXTTYPE_t_symptr0 FLEXTTPN_DEFSYM #define CALLBTYPE_t_symptr t_symptr #define FLEXTTYPE_t_symtype FLEXTTYPE_t_symptr #define FLEXTTYPE_t_symtype0 FLEXTTYPE_t_symptr0 #define CALLBTYPE_t_symtype t_symptr #define FLEXTTYPE_t_ptrtype FLEXTTPN_PTR #define CALLBTYPE_t_ptrtype t_ptrtype #define FLEXTTP(TP) FLEXTTYPE_ ## TP #define CALLBTP(TP) CALLBTYPE_ ## TP #define ARGMEMBER_bool(a) GetBool(a) #define ARGMEMBER_bool0(a) ARGMEMBER_bool(a) #define ARGMEMBER_int(a) GetInt(a) #define ARGMEMBER_int0(a) ARGMEMBER_int(a) #define ARGMEMBER_float(a) GetFloat(a) #define ARGMEMBER_float0(a) ARGMEMBER_float(a) #define ARGMEMBER_t_symptr(a) GetSymbol(a) #define ARGMEMBER_t_symptr0(a) ARGMEMBER_t_symptr(a) #define ARGMEMBER_t_symtype(a) ARGMEMBER_t_symptr(a) #define ARGMEMBER_t_symtype0(a) ARGMEMBER_t_symptr0(a) #define ARGCAST(a,tp) ARGMEMBER_##tp(a) #define REAL_NEW(NAME,NEW_CLASS,DSP,NOI,LIB) \ flext_obj *NEW_CLASS::__init__(int ,t_atom *) \ { \ return new NEW_CLASS; \ } \ FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ { \ flext_obj::obj_add(LIB,DSP,NOI,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,&NEW_CLASS::__free__,FLEXTTPN_NULL); \ } \ FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) #define REAL_NEW_V(NAME,NEW_CLASS,DSP,NOI,LIB) \ flext_obj *NEW_CLASS::__init__(int argc,t_atom *argv) \ { \ return new NEW_CLASS(argc,argv); \ } \ FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ { \ flext_obj::obj_add(LIB,DSP,NOI,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,&NEW_CLASS::__free__,FLEXTTPN_VAR,FLEXTTPN_NULL); \ } \ FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) #define REAL_NEW_1(NAME,NEW_CLASS,DSP,NOI,LIB, TYPE1) \ flext_obj *NEW_CLASS::__init__(int,t_atom *argv) \ { \ return new NEW_CLASS(ARGCAST(argv[0],TYPE1)); \ } \ FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ { \ flext_obj::obj_add(LIB,DSP,NOI,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),FLEXTTPN_NULL); \ } \ FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) #define REAL_NEW_2(NAME,NEW_CLASS,DSP,NOI,LIB, TYPE1,TYPE2) \ flext_obj *NEW_CLASS::__init__(int,t_atom *argv) \ { \ return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2)); \ } \ FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ { \ flext_obj::obj_add(LIB,DSP,NOI,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),FLEXTTP(TYPE2),FLEXTTPN_NULL); \ } \ FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) #define REAL_NEW_3(NAME,NEW_CLASS,DSP,NOI,LIB, TYPE1, TYPE2, TYPE3) \ flext_obj *NEW_CLASS::__init__(int,t_atom *argv) \ { \ return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2),ARGCAST(argv[2],TYPE3)); \ } \ FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ { \ flext_obj::obj_add(LIB,DSP,NOI,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),FLEXTTP(TYPE2),FLEXTTP(TYPE3),FLEXTTPN_NULL); \ } \ FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) #define REAL_NEW_4(NAME,NEW_CLASS,DSP,NOI,LIB, TYPE1,TYPE2, TYPE3, TYPE4) \ flext_obj *NEW_CLASS::__init__(int,t_atom *argv) \ { \ return new NEW_CLASS(ARGCAST(argv[0],TYPE1),ARGCAST(argv[1],TYPE2),ARGCAST(argv[2],TYPE3),ARGCAST(argv[3],TYPE4)); \ } \ FLEXT_EXP(LIB) void FLEXT_STPF(NEW_CLASS,DSP)() \ { \ flext_obj::obj_add(LIB,DSP,NOI,FLEXT_ATTRIBUTES,#NEW_CLASS,NAME,NEW_CLASS::__setup__,NEW_CLASS::__init__,NEW_CLASS::__free__,FLEXTTP(TYPE1),FLEXTTP(TYPE2),FLEXTTP(TYPE3),FLEXTTP(TYPE4),FLEXTTPN_NULL); \ } \ FLEXT_OBJ_SETUP(NEW_CLASS,DSP,LIB) // Shortcuts for method arguments: #define FLEXTARG_float a_float #define FLEXTARG_int a_int #define FLEXTARG_bool a_int #define FLEXTARG_t_float a_float #define FLEXTARG_t_symtype a_symbol #define FLEXTARG_t_symptr a_symbol #define FLEXTARG_t_ptrtype a_pointer #define FLEXTARG(TP) FLEXTARG_ ## TP #include "flpopns.h" #endif flext-0-6-3/source/flbind.cpp000066400000000000000000000214751446466241400161260ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flbind.cpp \brief Functionality for symbol-bound methods. */ #ifndef __FLEXT_BIND_CPP #define __FLEXT_BIND_CPP #include "flext.h" #include "flinternal.h" #include "flpushns.h" FLEXT_TEMPIMPL(t_class *FLEXT_CLASSDEF(flext_base))::pxbnd_class = NULL; #if FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPLATE struct ProxyVars { static t_object *px_freelist; static t_messlist px_messlist[3]; }; FLEXT_TEMPIMPL(t_object *ProxyVars)::px_freelist = NULL; FLEXT_TEMPIMPL(t_messlist ProxyVars)::px_messlist[3]; #endif /*! \brief Set up the proxy class for symbol-bound methods */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::SetupBindProxy() { // already initialized? if(!pxbnd_class) { #if FLEXT_SYS == FLEXT_SYS_PD pxbnd_class = class_new(gensym(const_cast("flext_base bind proxy")),NULL,NULL,sizeof(pxbnd_object),CLASS_PD|CLASS_NOINLET, A_NULL); add_anything(pxbnd_class,pxbnd_object::px_method); // for symbol-bound methods #elif FLEXT_SYS == FLEXT_SYS_MAX pxbnd_class = new t_class; pxbnd_class->c_sym = const_cast(sym__); pxbnd_class->c_freelist = &FLEXT_TEMPINST(ProxyVars)::px_freelist; pxbnd_class->c_freefun = NULL; pxbnd_class->c_size = sizeof(pxbnd_object); pxbnd_class->c_tiny = 0; pxbnd_class->c_noinlet = 1; FLEXT_TEMPINST(ProxyVars)::px_messlist[0].m_sym = (t_symbol *)pxbnd_class; FLEXT_TEMPINST(ProxyVars)::px_messlist[1].m_sym = const_cast(sym_anything); FLEXT_TEMPINST(ProxyVars)::px_messlist[1].m_fun = (method)pxbnd_object::px_method; FLEXT_TEMPINST(ProxyVars)::px_messlist[1].m_type[0] = A_GIMME; FLEXT_TEMPINST(ProxyVars)::px_messlist[1].m_type[1] = 0; FLEXT_TEMPINST(ProxyVars)::px_messlist[2].m_sym = 0; #else #pragma warning("Not implemented!") #endif } } FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::BindItem::BindItem(bool (*f)(flext_base *,t_symbol *s,int,t_atom *,void *data),pxbnd_object *p): Item(NULL),fun(f),px(p) {} FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::BindItem::~BindItem() { if(px) { FLEXT_ASSERT(!fun); // check if already unbound object_free(&px->obj); } } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::BindItem::Unbind(const t_symbol *tag) { if(px) { FLEXT_ASSERT(fun); #if FLEXT_SYS == FLEXT_SYS_PD pd_unbind(&px->obj.ob_pd,const_cast(tag)); #elif FLEXT_SYS == FLEXT_SYS_MAX if(tag->s_thing == (t_object *)px) const_cast(tag)->s_thing = NULL; else error("flext - Binding to symbol %s not found",tag->s_name); #else # pragma warning("Not implemented") #endif fun = NULL; } } #if FLEXT_SYS == FLEXT_SYS_PD //! Bind object to a symbol FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::Bind(const t_symbol *sym) { pd_bind(&thisHdr()->ob_pd,const_cast(sym)); return true; } //! Unbind object from a symbol FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::Unbind(const t_symbol *sym) { pd_unbind(&thisHdr()->ob_pd,const_cast(sym)); return true; } #elif FLEXT_SYS == FLEXT_SYS_MAX //! Bind object to a symbol FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::Bind(const t_symbol *sym) { if(sym->s_thing) return false; else { const_cast(sym)->s_thing = (t_object *)thisHdr(); return true; } } //! Unbind object from a symbol FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::Unbind(const t_symbol *sym) { if(sym->s_thing != (t_object *)thisHdr()) return false; else { const_cast(sym)->s_thing = NULL; return true; } } #endif FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::BindMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_symbol *s,int argc,t_atom *argv,void *data),void *data) { if(!bindhead) bindhead = new ItemCont; else { // Search for symbol for(Item *it = bindhead->FindList(sym); it; it = it->nxt) { BindItem *item = (BindItem *)it; // go through all items with matching tag if(item->fun == fun) { // function already registered -> bail out! post("%s - Symbol already bound with this method",thisName()); return false; } } } SetupBindProxy(); #if FLEXT_SYS == FLEXT_SYS_PD pxbnd_object *px = (pxbnd_object *)object_new(pxbnd_class); #elif FLEXT_SYS == FLEXT_SYS_MAX pxbnd_object *px = (pxbnd_object *)newobject(FLEXT_TEMPINST(ProxyVars)::px_messlist); #else #pragma warning("Not implemented!") #endif if(px) { BindItem *mi = new BindItem(fun,px); bindhead->Add(mi,sym); px->init(this,mi,data); #if FLEXT_SYS == FLEXT_SYS_PD pd_bind(&px->obj.ob_pd,const_cast(sym)); #elif FLEXT_SYS == FLEXT_SYS_MAX #if 1 // old code if(!sym->s_thing) const_cast(sym)->s_thing = (t_object *)px; else error("%s - Symbol is already bound",thisName()); #else void *binding = object_register(gensym("flext"),const_cast(sym),(t_object *)px); #endif #else # pragma warning("Not implemented") #endif } else error("%s - Symbol proxy could not be created",thisName()); return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::UnbindMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_symbol *s,int argc,t_atom *argv,void *data),void **data) { bool ok = false; if(bindhead && bindhead->Contained(0)) { ItemSet &set = bindhead->GetInlet(); /* ItemSet::iterator it1,it2; if(sym) { // specific tag it1 = it2 = set.find(sym); it2++; } else { // any tag it1 = set.begin(),it2 = set.end(); } BindItem *it = NULL; for(ItemSet::iterator si = it1; si != it2 && !it; ++si) { for(Item *i = si.data(); i; i = i->nxt) { BindItem *item = (BindItem *)i; if(!fun || item->fun == fun) { it = item; if(!sym) sym = si.key(); break; } } } */ BindItem *item = NULL; if(sym) { // symbol is given Item *it = set.find(sym); if(fun) { // check if function matches for(; it && static_cast(it)->fun != fun; it = it->nxt) {} } item = static_cast(it); } else { // take any entry that matches for(FLEXT_TEMP_TYPENAME ItemSet::iterator si(set); si && !item; ++si) { for(Item *i = si.data(); i; i = i->nxt) { BindItem *bit = (BindItem *)i; if(!fun || bit->fun == fun) { item = bit; if(!sym) sym = si.key(); break; } } } } if(item) { if(data) *data = item->px->data; ok = bindhead->Remove(item,sym,0,false); if(ok) { item->Unbind(sym); delete item; } } } return ok; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::GetBoundMethod(const t_symbol *sym,bool (*fun)(flext_base *,t_symbol *s,int argc,t_atom *argv,void *data),void *&data) { if(bindhead) { // Search for symbol for(Item *it = bindhead->FindList(sym); it; it = it->nxt) { BindItem *item = (BindItem *)it; // go through all items with matching tag if(item->fun == fun) { data = item->px->data; return true; } } } return false; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::UnbindAll() { if(bindhead && bindhead->Contained(0)) { ItemSet &set = bindhead->GetInlet(); // for(ItemSet::iterator si = set.begin(); si != set.end(); ++si) { for(FLEXT_TEMP_TYPENAME ItemSet::iterator si(set); si; ++si) { Item *lst = si.data(); while(lst) { Item *nxt = lst->nxt; BindItem *it = (BindItem *)lst; it->Unbind(si.key()); delete it; lst = nxt; } } set.clear(); } return true; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::pxbnd_object::px_method(pxbnd_object *c,const t_symbol *s,int argc,t_atom *argv) { c->item->fun(c->base,(t_symbol *)s,argc,(t_atom *)argv,c->data); } #include "flpopns.h" #endif // __FLEXT_BIND_CPP flext-0-6-3/source/flbuf.cpp000066400000000000000000000241541446466241400157630ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flbuf.cpp \brief Implementation of the buffer abstraction class. */ #ifndef __FLEXT_BUF_CPP #define __FLEXT_BUF_CPP #include "flext.h" #include "flfeatures.h" #include #include "flpushns.h" #if FLEXT_SYS == FLEXT_SYS_PD #define DIRTY_INTERVAL 0 // buffer dirty check in msec FLEXT_TEMPLATE class Buffers: public std::set { public: static FLEXT_TEMPINST(Buffers) buffers; }; FLEXT_TEMPIMPL(FLEXT_TEMPINST(Buffers) Buffers)::buffers; FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::cb_buffer_dsp(void *c,t_signal **sp) { FLEXT_UNUSED(c); FLEXT_UNUSED(sp); for(FLEXT_TEMPINST(Buffers)::iterator it = FLEXT_TEMPINST(Buffers)::buffers.begin(); it != FLEXT_TEMPINST(Buffers)::buffers.end(); ++it) (*it)->Set(); } #endif FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext))::buffer::buffer(const t_symbol *bn,bool delayed): sym(NULL),data(NULL), chns(0),frames(0) { #if FLEXT_SYS == FLEXT_SYS_PD arr = NULL; interval = DIRTY_INTERVAL; isdirty = false; ticking = false; // we probably should make this global... work on the set of registered buffers tick = clock_new(this,(t_method)cb_tick); #endif if(bn) Set(bn,delayed); ClearDirty(); #if FLEXT_SYS == FLEXT_SYS_PD // register buffer FLEXT_ASSERT(FLEXT_TEMPINST(Buffers)::buffers.find(this) == FLEXT_TEMPINST(Buffers)::buffers.end()); FLEXT_TEMPINST(Buffers)::buffers.insert(this); #endif } FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext))::buffer::~buffer() { #if FLEXT_SYS == FLEXT_SYS_PD if(tick) clock_free(tick); #endif #if FLEXT_SYS == FLEXT_SYS_PD // unregister buffer FLEXT_ASSERT(FLEXT_TEMPINST(Buffers)::buffers.find(this) != FLEXT_TEMPINST(Buffers)::buffers.end()); FLEXT_TEMPINST(Buffers)::buffers.erase(this); #endif } FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::buffer::Set(const t_symbol *s,bool nameonly) { int ret = 0; bool valid = data != NULL; // valid now? (before change) if(s && sym != s) { ret = 1; data = NULL; frames = 0; chns = 0; } if(s && *GetString(s)) sym = s; if(!sym) { if(valid) ret = -1; } else if(!nameonly) { #if FLEXT_SYS == FLEXT_SYS_PD arr = (t_garray *)pd_findbyclass(const_cast(sym), garray_class); if(!arr) { if (*GetString(sym)) FLEXT_LOG1("buffer: no such array '%s'",GetString(sym)); // sym = NULL; if(valid) ret = -1; } else { int frames1; FLEXT_ARRAYTYPE *data1; if(!FLEXT_PD_ARRAYGRAB(arr, &frames1, &data1)) { error("buffer: bad template '%s'",GetString(sym)); data = NULL; frames = 0; if(valid) ret = -1; } else { ret = 0; garray_usedindsp(arr); if(frames != frames1) { frames = frames1; if(!ret) ret = 1; } Element *data2 = reinterpret_cast(data1); if(data != data2) { data = data2; if(!ret) ret = 1; } chns = 1; } } #elif FLEXT_SYS == FLEXT_SYS_MAX if(sym->s_thing) { const t_buffer *p = (const t_buffer *)sym->s_thing; FLEXT_ASSERT(!NOGOOD(p)); if(ob_sym(p) != sym_buffer) { post("buffer: object '%s' not valid (type %s)",GetString(sym),GetString(ob_sym(p))); if(valid) ret = -2; } else { #ifdef FLEXT_DEBUG // post("flext: buffer object '%s' - valid:%i samples:%i channels:%i frames:%i",GetString(sym),p->b_valid,p->b_frames,p->b_nchans,p->b_frames); #endif Element *data1 = reinterpret_cast(p->b_samples); if(data != data1) { data = data1; if(!ret) ret = 1; } if(chns != p->b_nchans) { chns = p->b_nchans; if(!ret) ret = 1; } if(frames != p->b_frames) { frames = p->b_frames; if(!ret) ret = 1; } } } else { FLEXT_LOG1("buffer: symbol '%s' not defined", GetString(sym)); /*if(valid)*/ ret = -1; } #else #error not implemented #endif } return ret; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::buffer::Update() { FLEXT_ASSERT(sym); bool upd = false; #if FLEXT_SYS == FLEXT_SYS_PD if(!arr) return data == NULL; int frames1; FLEXT_ARRAYTYPE *data1; if(!FLEXT_PD_ARRAYGRAB(arr, &frames1, &data1)) { data = NULL; chns = 0; frames = 0; upd = true; } else { Element *data2 = reinterpret_cast(data1); if(data != data2 || frames != frames1) { data = data2; frames = frames1; upd = true; } } #elif FLEXT_SYS == FLEXT_SYS_MAX const t_buffer *p = (const t_buffer *)sym->s_thing; if(p) { FLEXT_ASSERT(!NOGOOD(p) && ob_sym(p) == sym_buffer); Element *data1 = reinterpret_cast(p->b_samples); if(data != data1 || chns != p->b_nchans || frames != p->b_frames) { data = data1; chns = p->b_nchans; frames = p->b_frames; upd = true; } } else { // buffer~ has e.g. been renamed data = NULL; chns = 0; frames = 0; upd = true; } #else #error not implemented #endif return upd; } FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext))::buffer::lock_t FLEXT_CLASSDEF(flext))::buffer::Lock() { FLEXT_ASSERT(sym); #if FLEXT_SYS == FLEXT_SYS_PD FLEXT_ASSERT(arr); #ifdef _FLEXT_HAVE_PD_GARRAYLOCKS garray_lock(arr); #endif return false; #elif FLEXT_SYS == FLEXT_SYS_MAX t_buffer *p = (t_buffer *)sym->s_thing; FLEXT_ASSERT(p); #ifdef _FLEXT_HAVE_MAX_INUSEFLAG long old = p->b_inuse; #ifdef ATOMIC_INCREMENT ATOMIC_INCREMENT(&p->b_inuse); #else p->b_inuse = 1; #endif return old; #else return 0; #endif #else #error not implemented #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::buffer::Unlock(flext::buffer::lock_t prv) { FLEXT_UNUSED(prv); // keep compiler quiet FLEXT_ASSERT(sym); #if FLEXT_SYS == FLEXT_SYS_PD FLEXT_ASSERT(arr); #ifdef _FLEXT_HAVE_PD_GARRAYLOCKS garray_unlock(arr); #endif #elif FLEXT_SYS == FLEXT_SYS_MAX t_buffer *p = (t_buffer *)sym->s_thing; FLEXT_ASSERT(p); #ifdef _FLEXT_HAVE_MAX_INUSEFLAG #ifdef ATOMIC_INCREMENT ATOMIC_DECREMENT(&p->b_inuse); #else p->b_inuse = prv; #endif #endif #else #error not implemented #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::buffer::Frames(int fr,bool keep,bool zero) { FLEXT_UNUSED(keep); // keep compiler quiet FLEXT_UNUSED(zero); // keep compiler quiet FLEXT_ASSERT(sym); #if FLEXT_SYS == FLEXT_SYS_PD // is this function guaranteed to keep memory and set rest to zero? ::garray_resize(arr,(float)fr); Update(); #elif FLEXT_SYS == FLEXT_SYS_MAX Element *tmp = NULL; int sz = frames; if(fr < sz) sz = fr; if(keep) { // copy buffer data to tmp storage tmp = (Element *)NewAligned(sz*sizeof(Element)); FLEXT_ASSERT(tmp); CopySamples(tmp,data,sz); } t_atom msg; t_buffer *buf = (t_buffer *)sym->s_thing; // b_msr reflects buffer sample rate... is this what we want? // Max bug: adding half a sample to prevent roundoff errors.... float ms = (fr+0.5)/buf->b_msr; SetFloat(msg,ms); ::typedmess((object *)buf,(t_symbol *)sym_size,1,&msg); Update(); if(tmp) { // copy data back CopySamples(data,tmp,sz); FreeAligned(tmp); if(zero && sz < fr) ZeroSamples(data+sz,fr-sz); } else if(zero) ZeroSamples(data,fr); #else #error #endif } #if FLEXT_SYS == FLEXT_SYS_PD FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::buffer::SetRefrIntv(float intv) { interval = intv; if(interval == 0 && ticking) { clock_unset(tick); ticking = false; } } #elif FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::buffer::SetRefrIntv(float) {} #else #error #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::buffer::Dirty(bool force) { FLEXT_ASSERT(sym); #if FLEXT_SYS == FLEXT_SYS_PD if((!ticking) && (interval || force)) { ticking = true; cb_tick(this); // immediately redraw } else { if(force) clock_delay(tick,0); isdirty = true; } #elif FLEXT_SYS == FLEXT_SYS_MAX t_buffer *p = (t_buffer *)sym->s_thing; FLEXT_ASSERT(p && !NOGOOD(p)); // object_method function is redirected to object_method_imp on 64-bit Max // which in turn doesn't exist. Use object_method_typed instead. t_atom rv; object_method_typed((t_object *)p,(t_symbol *)sym_dirty,0,NULL,&rv); // p->b_modtime = gettime(); #else #error Not implemented #endif } #if FLEXT_SYS == FLEXT_SYS_PD FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::buffer::cb_tick(buffer *b) { if(b->arr) garray_redraw(b->arr); #ifdef FLEXT_DEBUG else error("buffer: array is NULL"); #endif if(b->isdirty && b->interval) { b->isdirty = false; b->ticking = true; clock_delay(b->tick,b->interval); } else b->ticking = false; } #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::buffer::ClearDirty() { #if FLEXT_SYS == FLEXT_SYS_PD cleantime = clock_getlogicaltime(); #elif FLEXT_SYS == FLEXT_SYS_MAX cleantime = gettime(); #else #error Not implemented #endif } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::buffer::IsDirty() const { if(!sym) return false; #if FLEXT_SYS == FLEXT_SYS_PD #ifdef _FLEXT_HAVE_PD_GARRAYUPDATETIME return arr && (isdirty || garray_updatetime(arr) > cleantime); #else // Don't know.... (no method in PD judging whether buffer has been changed from outside flext...) return true; #endif #elif FLEXT_SYS == FLEXT_SYS_MAX t_buffer *p = (t_buffer *)sym->s_thing; FLEXT_ASSERT(p && !NOGOOD(p)); return p->b_modtime > cleantime; #else #error Not implemented #endif } #include "flpopns.h" #endif // __FLEXT_BUF_CPP flext-0-6-3/source/flclass.h000066400000000000000000001420121446466241400157530ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2017 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flclass.h \brief User accessible flext base classes */ #ifndef __FLCLASS_H #define __FLCLASS_H // include the header file declaring the base classes #include "flbase.h" #include "flsupport.h" #include "flmap.h" #include "flinternal.h" #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #ifdef __BORLANDC__ #pragma warn -8008 // Condition is always false #pragma warn -8057 // Parameter is never used #pragma warn -8066 // Unreachable code #endif #include "flpushns.h" // === flext_base ================================================== /*! \brief Flext message only base object This is the base class from which typical external objects derive. DSP objects should use the flext_dsp class which inherits from flext_base and provides the necessary functionality. For a valid external object class you would also need FLEXT_HEADER, also if it's only a base class without instantiated objects again. To make an instance of an object class you would typically use FLEXT_NEW or its companions. See the flext_obj class for additional information. */ FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_base); typedef class FLEXT_SHARE FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_base)) flext_base; FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_base): public flext_obj { FLEXT_HEADER_S(FLEXT_CLASSDEF(flext_base),flext_obj,Setup) friend class FLEXT_SHARE FLEXT_CLASSDEF(flext_obj); public: // --- inheritable virtual methods -------------------------------- /*! \defgroup FLEXT_C_VIRTUAL Virtual base class functions @{ */ //! called on patcher load (not on mere object creation!) virtual void CbLoadbang(); virtual void m_loadbang(); //! called on (double-)click into object box virtual void CbClick(); /*! \brief Called for every incoming message. All method handling is done in there \return True if a handler was found and called */ virtual bool CbMethodHandler(int inlet,const t_symbol *s,int argc,const t_atom *argv); /*! \brief Called for every unhandled message (by CbMethodHandler) */ virtual bool CbMethodResort(int inlet,const t_symbol *s,int argc,const t_atom *argv); virtual bool m_method_(int inlet,const t_symbol *s,int argc,const t_atom *argv); virtual bool CbIdle(); //! @} FLEXT_C_VIRTUAL // --- inlet/outlet stuff ----------------------------------------- /*! \defgroup FLEXT_C_INOUT Flext in-/outlet functions \note These must be called in the class' constructor \note All (also default) inlets must be defined @{ */ /*! \defgroup FLEXT_C_IO_ADD Announce in-/outlet functions @{ */ // argument m specifies multiple inlet/outlet count // void AddInDef() { AddInlet(xlet_def,1); } /*! \brief Add inlet(s) for anythings \remark That's the one to choose for the left-most (first) inlet unless it's a signal inlet. */ void AddInAnything(int m = 1) { AddInlet(xlet_any,m); } /*! \brief Add inlet(s) for anythings (with description) \remark That's the one to choose for the left-most (first) inlet unless it's a signal inlet. */ void AddInAnything(const char *desc,int m = 1) { AddInlet(xlet_any,m,desc); } //! Add inlet(s) for floats void AddInFloat(int m = 1) { AddInlet(xlet_float,m); } //! Add inlet(s) for floats (with description) void AddInFloat(const char *desc,int m = 1) { AddInlet(xlet_float,m,desc); } //! Add inlet(s) for integers void AddInInt(int m = 1) { AddInlet(xlet_int,m); } //! Add inlet(s) for integers (with description) void AddInInt(const char *desc,int m = 1) { AddInlet(xlet_int,m,desc); } //! Add inlet(s) for symbols void AddInSymbol(int m = 1) { AddInlet(xlet_sym,m); } //! Add inlet(s) for symbol (with description) void AddInSymbol(const char *desc,int m = 1) { AddInlet(xlet_sym,m,desc); } //! Add inlet(s) for bang void AddInBang(int m = 1) { AddInlet(xlet_sym,m); } //! Add inlet(s) for bangs (with description) void AddInBang(const char *desc,int m = 1) { AddInlet(xlet_sym,m,desc); } //! Add inlet(s) for lists void AddInList(int m = 1) { AddInlet(xlet_list,m); } //! Add inlet(s) for lists (with description) void AddInList(const char *desc,int m = 1) { AddInlet(xlet_list,m,desc); } //! Add outlet(s) for anythings void AddOutAnything(int m = 1) { AddOutlet(xlet_any,m); } //! Add outlet(s) for anythings (with description) void AddOutAnything(const char *desc,int m = 1) { AddOutlet(xlet_any,m,desc); } //! Add outlet(s) for floats void AddOutFloat(int m = 1) { AddOutlet(xlet_float,m); } //! Add outlet(s) for floats (with description) void AddOutFloat(const char *desc,int m = 1) { AddOutlet(xlet_float,m,desc); } //! Add outlet(s) for integers void AddOutInt(int m = 1) { AddOutlet(xlet_int,m); } //! Add outlet(s) for integers (with description) void AddOutInt(const char *desc,int m = 1) { AddOutlet(xlet_int,m,desc); } //! Add outlet(s) for symbols void AddOutSymbol(int m = 1) { AddOutlet(xlet_sym,m); } //! Add outlet(s) for symbols (with description) void AddOutSymbol(const char *desc,int m = 1) { AddOutlet(xlet_sym,m,desc); } //! Add outlet(s) for bangs void AddOutBang(int m = 1) { AddOutlet(xlet_sym,m); } //! Add outlet(s) for bangs (with description) void AddOutBang(const char *desc,int m = 1) { AddOutlet(xlet_sym,m,desc); } //! Add outlet(s) for lists void AddOutList(int m = 1) { AddOutlet(xlet_list,m); } //! Add outlet(s) for lists (with description) void AddOutList(const char *desc,int m = 1) { AddOutlet(xlet_list,m,desc); } //! \deprecated inlets and outlets are now set up automatically bool SetupInOut() { return true; } //! @} FLEXT_C_IO_ADD /*! \defgroup FLEXT_C_IO_MISC Miscellanous in-/outlet functionality @{ */ //! Get number of inlets int CntIn() const { return incnt; } //! Get number of outlets int CntOut() const { return outcnt; } //! Get number of signal inlets int CntInSig() const { return insigs; } //! Get number of signal outlets int CntOutSig() const { return outsigs; } //! Retrieve currently processed message tag (NULL if no message processing) static const t_symbol *thisTag() { return curtag; } class outlet; //! Get pointer to outlet (not in the constructor!) outlet *GetOut(int ix) const { return outlets[ix]; } int GetOutAttr() const { return HasAttributes()?CntOut():0; } //! @} FLEXT_C_IO_MISC /*! \defgroup FLEXT_C_IO_OUT Output data to inlets/outlets @{ */ // output messages //! Output bang (index n starts with 0) void ToOutBang(int n) const; //! Output float (index n starts with 0) void ToOutFloat(int n,float f) const; //! Output integer (index n starts with 0) void ToOutInt(int n,int f) const; //! Output boolean (index n starts with 0) void ToOutBool(int n,bool f) const { ToOutInt(n,f?1:0); } //! Output double (index n starts with 0) void ToOutDouble(int n,double d) const { t_atom dbl[2]; ToOutList(n,2,SetDouble(dbl,d)); } //! Output symbol (index n starts with 0) void ToOutSymbol(int n,const t_symbol *s) const; //! Output string aka symbol (index n starts with 0) void ToOutString(int n,const char *s) const { ToOutSymbol(n,MakeSymbol(s)); } //! Output atom (index n starts with 0) void ToOutAtom(int n,const t_atom &at) const; //! Output list (index n starts with 0) void ToOutList(int n,int argc,const t_atom *argv) const; //! Output list (index n starts with 0) void ToOutList(int n,const AtomList &list) const { ToOutList(n,list.Count(),list.Atoms()); } //! Output anything (index n starts with 0) void ToOutAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const; //! Output anything (index n starts with 0) void ToOutAnything(int n,const AtomAnything &any) const { ToOutAnything(n,any.Header(),any.Count(),any.Atoms()); } //! Output anything (index n starts with 0) void ToOutAnything(int n,const t_symbol *s,const AtomList &list) const { ToOutAnything(n,s,list.Count(),list.Atoms()); } //! @} FLEXT_C_IO_OUT /*! \defgroup FLEXT_C_IO_QUEUE Low-priority output of data to inlets/outlets @{ */ //! Output low priority bang (index n starts with 0) void ToQueueBang(int n) const; //! Output low priority float (index n starts with 0) void ToQueueFloat(int n,float f) const; //! Output low priority integer (index n starts with 0) void ToQueueInt(int n,int f) const; //! Output low priority boolean (index n starts with 0) void ToQueueBool(int n,bool f) const { ToQueueInt(n,f?1:0); } //! Output double (index n starts with 0) void ToQueueDouble(int n,double d) const { t_atom dbl[2]; ToQueueList(n,2,SetDouble(dbl,d)); } //! Output low priority symbol (index n starts with 0) void ToQueueSymbol(int n,const t_symbol *s) const; //! Output low priority string aka symbol (to appointed outlet) void ToQueueString(int n,const char *s) const { ToQueueSymbol(n,MakeSymbol(s)); } //! Output low priority atom (index n starts with 0) void ToQueueAtom(int n,const t_atom &at) const; //! Output low priority list (index n starts with 0) void ToQueueList(int n,int argc,const t_atom *argv) const; //! Output low priority list (index n starts with 0) void ToQueueList(int n,const AtomList &list) const { ToQueueList(n,list.Count(),list.Atoms()); } //! Output low priority anything (index n starts with 0) void ToQueueAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const; //! Output low priority anything (index n starts with 0) void ToQueueAnything(int n,const AtomAnything &any) const { ToQueueAnything(n,any.Header(),any.Count(),any.Atoms()); } //! @} FLEXT_C_IO_QUEUE /*! \defgroup FLEXT_C_IO_SELF Output of data to inlets/outlets of this object @{ */ //! Send bang to self (inlet n) void ToSelfBang(int n) const { ToQueueBang(-1-n); } //! Send float to self (inlet n) void ToSelfFloat(int n,float f) const { ToQueueFloat(-1-n,f); } //! Send integer to self (inlet n) void ToSelfInt(int n,int f) const { ToQueueInt(-1-n,f); } //! Send boolean to self (inlet n) void ToSelfBool(int n,bool f) const { ToSelfInt(n,f?1:0); } //! Send double to self (index n starts with 0) void ToSelfDouble(int n,double d) const { t_atom dbl[2]; ToSelfList(n,2,SetDouble(dbl,d)); } //! Send symbol to self (inlet n) void ToSelfSymbol(int n,const t_symbol *s) const { ToQueueSymbol(-1-n,s); } //! Send string aka symbol to self (inlet 0) void ToSelfString(int n,const char *s) const { ToSelfSymbol(n,MakeSymbol(s)); } //! Output atom (index n starts with 0) void ToSelfAtom(int n,const t_atom &at) const { ToQueueAtom(-1-n,at); } //! Send list to self (inlet n) void ToSelfList(int n,int argc,const t_atom *argv) const { ToQueueList(-1-n,argc,argv); } //! Send list to self (inlet n) void ToSelfList(int n,const AtomList &list) const { ToSelfList(n,list.Count(),list.Atoms()); } //! Send anything to self (inlet n) void ToSelfAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { ToQueueAnything(-1-n,s,argc,argv); } //! Send anything to self (inlet n) void ToSelfAnything(int n,const AtomAnything &any) const { ToSelfAnything(n,any.Header(),any.Count(),any.Atoms()); } //! @} FLEXT_C_IO_SELF /*! \defgroup FLEXT_C_IO_MESSAGEBUNDLE Output of data via message bundles These are used to assure the sending of several messages from a second thread to the same logical time @{ */ //! Output bang (index n starts with 0) void MsgAddBang(MsgBundle *mb,int n) const; //! Output float (index n starts with 0) void MsgAddFloat(MsgBundle *mb,int n,float f) const; //! Output integer (index n starts with 0) void MsgAddInt(MsgBundle *mb,int n,int f) const; //! Output boolean (index n starts with 0) void MsgAddBool(MsgBundle *mb,int n,bool f) const { MsgAddInt(mb,n,f?1:0); } //! Output double (index n starts with 0) void MsgAddDouble(MsgBundle *mb,int n,double d) const { t_atom dbl[2]; MsgAddList(mb,n,2,SetDouble(dbl,d)); } //! Output symbol (index n starts with 0) void MsgAddSymbol(MsgBundle *mb,int n,const t_symbol *s) const; //! Output string aka symbol (to appointed outlet) void MsgAddString(MsgBundle *mb,int n,const char *s) const { MsgAddSymbol(mb,n,MakeSymbol(s)); } //! Output atom (index n starts with 0) void MsgAddAtom(MsgBundle *mb,int n,const t_atom &at) const; //! Output list (index n starts with 0) void MsgAddList(MsgBundle *mb,int n,int argc,const t_atom *argv) const; //! Output list (index n starts with 0) void MsgAddList(MsgBundle *mb,int n,const AtomList &list) const { MsgAddList(mb,n,list.Count(),list.Atoms()); } //! Output anything (index n starts with 0) void MsgAddAnything(MsgBundle *mb,int n,const t_symbol *s,int argc,const t_atom *argv) const; //! Output anything (index n starts with 0) void MsgAddAnything(MsgBundle *mb,int n,const AtomAnything &any) const { MsgAddAnything(mb,n,any.Header(),any.Count(),any.Atoms()); } void MsgSelfBang(MsgBundle *mb,int n) const { MsgAddBang(mb,-1-n); } //! Send float to self (inlet n) void MsgSelfFloat(MsgBundle *mb,int n,float f) const { MsgAddFloat(mb,-1-n,f); } //! Send integer to self (inlet n) void MsgSelfInt(MsgBundle *mb,int n,int f) const { MsgAddInt(mb,-1-n,f); } //! Send boolean to self (inlet n) void MsgSelfBool(MsgBundle *mb,int n,bool f) const { MsgSelfInt(mb,n,f?1:0); } //! Output double (index n starts with 0) void MsgSelfDouble(MsgBundle *mb,int n,double d) const { t_atom dbl[2]; MsgSelfList(mb,n,2,SetDouble(dbl,d)); } //! Send symbol to self (inlet n) void MsgSelfSymbol(MsgBundle *mb,int n,const t_symbol *s) const { MsgAddSymbol(mb,-1-n,s); } //! Send string aka symbol to self (inlet 0) void MsgSelfString(MsgBundle *mb,int n,const char *s) const { MsgSelfSymbol(mb,n,MakeSymbol(s)); } //! Output atom (index n starts with 0) void MsgSelfAtom(MsgBundle *mb,int n,const t_atom &at) const { MsgAddAtom(mb,-1-n,at); } //! Send list to self (inlet n) void MsgSelfList(MsgBundle *mb,int n,int argc,const t_atom *argv) const { MsgAddList(mb,-1-n,argc,argv); } //! Send list to self (inlet n) void MsgSelfList(MsgBundle *mb,int n,const AtomList &list) const { MsgSelfList(mb,n,list.Count(),list.Atoms()); } //! Send anything to self (inlet n) void MsgSelfAnything(MsgBundle *mb,int n,const t_symbol *s,int argc,const t_atom *argv) const { MsgAddAnything(mb,-1-n,s,argc,argv); } //! Send anything to self (inlet n) void MsgSelfAnything(MsgBundle *mb,int n,const AtomAnything &any) const { MsgSelfAnything(mb,n,any.Header(),any.Count(),any.Atoms()); } //! @} FLEXT_C_IO_MESSAGEBUNDLE //! @} FLEXT_C_INOUT // --- message handling ------------------------------------------- enum { a_null = 0, a_float,a_int,a_bool, a_symbol,a_pointer, a_list,a_any, // (t_symbol *) / int / t_atom * a_LIST,a_ANY // AtomList, AtomAnything }; typedef bool (*methfun)(flext_base *c); /*! \defgroup FLEXT_C_ADDMETHOD Method handling (object scope) \internal @{ */ void AddMethodDef(int inlet,const t_symbol *tag = NULL) { ThMeths()->Add(new MethItem,tag,inlet); } void AddMethodDef(int inlet,const char *tag = NULL) { AddMethodDef(inlet,MakeSymbol(tag)); } void AddMethod(int inlet,bool (*m)(flext_base *)) { AddMethod(ThMeths(),inlet,sym_bang,(methfun)m,a_null); } void AddMethod(int inlet,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(ThMeths(),inlet,sym_list,(methfun)m,a_list,a_null); } void AddMethod(int inlet,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(ThMeths(),inlet,sym_list,(methfun)m,a_list,a_null); } void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_null); } // pure method void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *)) { AddMethod(inlet,MakeSymbol(tag),m); } void AddMethod(int inlet,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(ThMeths(),inlet,sym_anything,(methfun)m,a_any,a_null); } // anything void AddMethod(int inlet,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(ThMeths(),inlet,sym_anything,(methfun)m,a_any,a_null); } // anything void AddMethod(int inlet,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(ThMeths(),inlet,sym_symbol,(methfun)m,a_symbol,a_null); } // single symbol void AddMethod(int inlet,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(ThMeths(),inlet,sym_symbol,(methfun)m,a_symbol,a_null); } // single symbol void AddMethod(int inlet,bool (*m)(flext_base *,float &)) { AddMethod(ThMeths(),inlet,sym_float,(methfun)m,a_float,a_null); } // single float void AddMethod(int inlet,bool (*m)(flext_base *,float &,float &)) { AddMethod(ThMeths(),inlet,sym_list,(methfun)m,a_float,a_float,a_null); } // list of 2 floats void AddMethod(int inlet,bool (*m)(flext_base *,float &,float &,float &)) { AddMethod(ThMeths(),inlet,sym_list,(methfun)m,a_float,a_float,a_float,a_null); } // list of 3 floats #if FLEXT_SYS == FLEXT_SYS_PD void AddMethod(int inlet,bool (*m)(flext_base *,int &)) { AddMethod(ThMeths(),inlet,sym_float,(methfun)m,a_int,a_null); } // single float #else void AddMethod(int inlet,bool (*m)(flext_base *,int &)) { AddMethod(ThMeths(),inlet,sym_int,(methfun)m,a_int,a_null); } // single float #endif void AddMethod(int inlet,bool (*m)(flext_base *,int &,int &)) { AddMethod(ThMeths(),inlet,sym_list,(methfun)m,a_int,a_int,a_null); } // list of 2 floats void AddMethod(int inlet,bool (*m)(flext_base *,int &,int &,int &)) { AddMethod(ThMeths(),inlet,sym_list,(methfun)m,a_int,a_int,a_int,a_null); } // list of 3 floats void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_list,a_null); } // method+gimme void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_list,a_null); } // method+gimme void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_any,a_null); } // method+gimme void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_any,a_null); } // method+gimme void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *,float &)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_float,a_null); } // method+float void AddMethod(int inlet,const t_symbol *tag,bool (*m)(flext_base *,int &)) { AddMethod(ThMeths(),inlet,tag,(methfun)m,a_int,a_null); } // method+int void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(inlet,MakeSymbol(tag),m); } void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(inlet,MakeSymbol(tag),m); } void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(inlet,MakeSymbol(tag),m); } void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(inlet,MakeSymbol(tag),m); } void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(inlet,MakeSymbol(tag),m); } void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(inlet,MakeSymbol(tag),m); } void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,float &)) { AddMethod(inlet,MakeSymbol(tag),m); } void AddMethod(int inlet,const char *tag,bool (*m)(flext_base *,int &)) { AddMethod(inlet,MakeSymbol(tag),m); } // Â¥schedule call of the CbIdle method during the next idle cycle void AddIdle(); //! Set Max/MSP style of distributing list elements over (message) inlets static void SetDist(t_classid c,bool d = true); //! Query whether lists are distributed bool DoDist() const; //! @} FLEXT_C_ADDMETHOD /*! \defgroup FLEXT_C_CADDMETHOD Method handling (class scope) \internal @{ */ static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *)) { AddMethod(ClMeths(c),inlet,sym_bang,(methfun)m,a_null); } static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,sym_list,(methfun)m,a_list,a_null); } static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,sym_list,(methfun)m,a_list,a_null); } static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_null); } // pure method static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *)) { AddMethod(c,inlet,MakeSymbol(tag),m); } static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,sym_anything,(methfun)m,a_any,a_null); } // anything static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,sym_anything,(methfun)m,a_any,a_null); } // anything static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(ClMeths(c),inlet,sym_symbol,(methfun)m,a_symbol,a_null); } // single symbol static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(ClMeths(c),inlet,sym_symbol,(methfun)m,a_symbol,a_null); } // single symbol static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,float &)) { AddMethod(ClMeths(c),inlet,sym_float,(methfun)m,a_float,a_null); } // single float static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,float &,float &)) { AddMethod(ClMeths(c),inlet,sym_list,(methfun)m,a_float,a_float,a_null); } // list of 2 floats static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,float &,float &,float &)) { AddMethod(ClMeths(c),inlet,sym_list,(methfun)m,a_float,a_float,a_float,a_null); } // list of 3 floats #if FLEXT_SYS == FLEXT_SYS_PD static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,sym_float,(methfun)m,a_int,a_null); } // single integer #else static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,sym_int,(methfun)m,a_int,a_null); } // single integer #endif static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int &,int &)) { AddMethod(ClMeths(c),inlet,sym_list,(methfun)m,a_int,a_int,a_null); } // list of 2 floats static void AddMethod(t_classid c,int inlet,bool (*m)(flext_base *,int &,int &,int &)) { AddMethod(ClMeths(c),inlet,sym_list,(methfun)m,a_int,a_int,a_int,a_null); } // list of 3 floats static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_list,a_null); } // method+gimme static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_list,a_null); } // method+gimme static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_any,a_null); } // method+gimme static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_any,a_null); } // method+gimme static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_symbol,a_null); } // method+symbol static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *,float &)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_float,a_null); } // method+float static void AddMethod(t_classid c,int inlet,const t_symbol *tag,bool (*m)(flext_base *,int &)) { AddMethod(ClMeths(c),inlet,tag,(methfun)m,a_int,a_null); } // method+int static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,int,t_atom *)) { AddMethod(c,inlet,MakeSymbol(tag),m); } static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,int,const t_atom *)) { AddMethod(c,inlet,MakeSymbol(tag),m); } static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *,int,t_atom *)) { AddMethod(c,inlet,MakeSymbol(tag),m); } static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *,int,const t_atom *)) { AddMethod(c,inlet,MakeSymbol(tag),m); } static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,t_symbol *&)) { AddMethod(c,inlet,MakeSymbol(tag),m); } static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,const t_symbol *&)) { AddMethod(c,inlet,MakeSymbol(tag),m); } static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,float &)) { AddMethod(c,inlet,MakeSymbol(tag),m); } static void AddMethod(t_classid c,int inlet,const char *tag,bool (*m)(flext_base *,int &)) { AddMethod(c,inlet,MakeSymbol(tag),m); } // Â¥schedule call of the given idlefun during the next idle cycle static void AddIdle(bool (*idlefun)(int argc,const t_atom *argv),int argc,const t_atom *argv); //! @} FLEXT_C_CADDMETHOD // --- bind/unbind --------------------------------------- /*! \defgroup FLEXT_C_BIND Methods for binding a flext class to a symbol @{ */ //! Bind object to a symbol bool Bind(const t_symbol *sym); //! Unbind object from a symbol bool Unbind(const t_symbol *sym); //! Bind object to a symbol (as string) bool Bind(const char *sym) { return Bind(MakeSymbol(sym)); } //! Unbind object from a symbol (as string) bool Unbind(const char *sym) { return Unbind(MakeSymbol(sym)); } /*! \brief Bind a method to a symbol \param sym Symbol to bind to \param meth Function to bind \param data User data that is passed to the function \return true on success */ bool BindMethod(const t_symbol *sym,bool (*meth)(flext_base *obj,t_symbol *sym,int argc,t_atom *argv,void *data),void *data = NULL); /*! \brief Unbind a method from a symbol \param sym Symbol to unbind from (if NULL... unbind all functions) \param meth Method to unbind (if NULL ... unbind all functions bound to symbol) \param data returns data pointer specified with BindMethod \return true on success */ bool UnbindMethod(const t_symbol *sym,bool (*meth)(flext_base *obj,t_symbol *sym,int argc,t_atom *argv,void *data) = NULL,void **data = NULL); /*! \brief Get data of bound method of a symbol \param sym Symbol to bind to \param meth Function to bind \param data Reference to returned user data \return true on success (symbol/method combination was found) */ bool GetBoundMethod(const t_symbol *sym,bool (*meth)(flext_base *obj,t_symbol *sym,int argc,t_atom *argv,void *data),void *&data); //! \brief Bind a method to a symbol (as string) bool BindMethod(const char *sym,bool (*meth)(flext_base *obj,t_symbol *sym,int argc,t_atom *argv,void *data),void *data = NULL) { return BindMethod(MakeSymbol(sym),meth,data); } //! \brief Unbind a method from a symbol (as string) bool UnbindMethod(const char *sym,bool (*meth)(flext_base *obj,t_symbol *sym,int argc,t_atom *argv,void *data) = NULL,void **data = NULL) { return UnbindMethod(MakeSymbol(sym),meth,data); } //! \brief Get data of bound method of a symbol (as string) bool GetBoundMethod(const char *sym,bool (*meth)(flext_base *obj,t_symbol *sym,int argc,t_atom *argv,void *data),void *&data) { return GetBoundMethod(MakeSymbol(sym),meth,data); } /*! Unbind all symbol bindings \note Memory associated to data pointers passed by BindMethod will not be freed! */ bool UnbindAll(); //! @} FLEXT_C_BIND // --- thread stuff ----------------------------------------------- #ifdef FLEXT_THREADS /*! \defgroup FLEXT_C_THREAD Thread handling @{ */ //! Start a thread for this object bool StartThread(void (*meth)(thr_params *p),thr_params *p,const char * = NULL) { p->cl = this; return flext::LaunchThread(meth,p); } //! Terminate all threads of this object bool StopThreads(); #endif // FLEXT_THREADS //! @} FLEXT_C_THREAD // xxx internal stuff xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx public: // needed by VC++ 6 enum { xlet_none = 0, xlet_float,xlet_int,xlet_sym,xlet_list,xlet_any, xlet_LIST,xlet_ANY, // use AtomList and AtomAnything xlet_sig }; protected: FLEXT_CLASSDEF(flext_base)(); /*! \brief Set up inlets and outlets, method and attribute lists */ virtual bool Init(); /*! \brief Deallocate all kinds of stuff */ virtual void Exit(); /*! \defgroup FLEXT_C_ATTR Attribute handling methods (object scope) @{ */ void AddAttrib(const t_symbol *attr,bool (*get)(flext_base *,float &),bool (*set)(flext_base *,float &)) { AddAttrib(attr,a_float,(methfun)get,(methfun)set); } void AddAttrib(const t_symbol *attr,bool (*get)(flext_base *,int &),bool (*set)(flext_base *,int &)) { AddAttrib(attr,a_int,(methfun)get,(methfun)set); } void AddAttrib(const t_symbol *attr,bool (*get)(flext_base *,bool &),bool (*set)(flext_base *,bool &)) { AddAttrib(attr,a_bool,(methfun)get,(methfun)set); } void AddAttrib(const t_symbol *attr,bool (*get)(flext_base *,const t_symbol *&),bool (*set)(flext_base *,const t_symbol *&)) { AddAttrib(attr,a_symbol,(methfun)get,(methfun)set); } void AddAttrib(const t_symbol *attr,bool (*get)(flext_base *,t_symptr &),bool (*set)(flext_base *,t_symptr &)) { AddAttrib(attr,a_symbol,(methfun)get,(methfun)set); } void AddAttrib(const t_symbol *attr,bool (*get)(flext_base *,AtomList *&),bool (*set)(flext_base *,AtomList *&)) { AddAttrib(attr,a_LIST,(methfun)get,(methfun)set); } void AddAttrib(const t_symbol *attr,bool (*get)(flext_base *,AtomAnything *&),bool (*set)(flext_base *,AtomAnything *&)) { AddAttrib(attr,a_ANY,(methfun)get,(methfun)set); } void AddAttrib(const char *attr,bool (*get)(flext_base *,float &),bool (*set)(flext_base *,float &)) { AddAttrib(MakeSymbol(attr),get,set); } void AddAttrib(const char *attr,bool (*get)(flext_base *,int &),bool (*set)(flext_base *,int &)) { AddAttrib(MakeSymbol(attr),get,set); } void AddAttrib(const char *attr,bool (*get)(flext_base *,bool &),bool (*set)(flext_base *,bool &)) { AddAttrib(MakeSymbol(attr),get,set); } void AddAttrib(const char *attr,bool (*get)(flext_base *,const t_symbol *&),bool (*set)(flext_base *,const t_symbol *&)) { AddAttrib(MakeSymbol(attr),get,set); } void AddAttrib(const char *attr,bool (*get)(flext_base *,t_symptr &),bool (*set)(flext_base *,t_symptr &)) { AddAttrib(MakeSymbol(attr),get,set); } void AddAttrib(const char *attr,bool (*get)(flext_base *,AtomList *&),bool (*set)(flext_base *,AtomList *&)) { AddAttrib(MakeSymbol(attr),get,set); } void AddAttrib(const char *attr,bool (*get)(flext_base *,AtomAnything *&),bool (*set)(flext_base *,AtomAnything *&)) { AddAttrib(MakeSymbol(attr),get,set); } //! @} FLEXT_C_ATTR /*! \defgroup FLEXT_C_CATTR Attribute handling methods (class scope) @{ */ static void AddAttrib(t_classid c,const t_symbol *attr,bool (*get)(flext_base *,float &),bool (*set)(flext_base *,float &)) { AddAttrib(c,attr,a_float,(methfun)get,(methfun)set); } static void AddAttrib(t_classid c,const t_symbol *attr,bool (*get)(flext_base *,int &),bool (*set)(flext_base *,int &)) { AddAttrib(c,attr,a_int,(methfun)get,(methfun)set); } static void AddAttrib(t_classid c,const t_symbol *attr,bool (*get)(flext_base *,bool &),bool (*set)(flext_base *,bool &)) { AddAttrib(c,attr,a_bool,(methfun)get,(methfun)set); } static void AddAttrib(t_classid c,const t_symbol *attr,bool (*get)(flext_base *,const t_symbol *&),bool (*set)(flext_base *,const t_symbol *&)) { AddAttrib(c,attr,a_symbol,(methfun)get,(methfun)set); } static void AddAttrib(t_classid c,const t_symbol *attr,bool (*get)(flext_base *,t_symptr &),bool (*set)(flext_base *,t_symptr &)) { AddAttrib(c,attr,a_symbol,(methfun)get,(methfun)set); } static void AddAttrib(t_classid c,const t_symbol *attr,bool (*get)(flext_base *,AtomList *&),bool (*set)(flext_base *,AtomList *&)) { AddAttrib(c,attr,a_LIST,(methfun)get,(methfun)set); } static void AddAttrib(t_classid c,const t_symbol *attr,bool (*get)(flext_base *,AtomAnything *&),bool (*set)(flext_base *,AtomAnything *&)) { AddAttrib(c,attr,a_ANY,(methfun)get,(methfun)set); } static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,float &),bool (*set)(flext_base *,float &)) { AddAttrib(c,MakeSymbol(attr),get,set); } static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,int &),bool (*set)(flext_base *,int &)) { AddAttrib(c,MakeSymbol(attr),get,set); } static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,bool &),bool (*set)(flext_base *,bool &)) { AddAttrib(c,MakeSymbol(attr),get,set); } static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,const t_symbol *&),bool (*set)(flext_base *,const t_symbol *&)) { AddAttrib(c,MakeSymbol(attr),get,set); } static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,t_symptr &),bool (*set)(flext_base *,t_symptr &)) { AddAttrib(c,MakeSymbol(attr),get,set); } static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,AtomList *&),bool (*set)(flext_base *,AtomList *&)) { AddAttrib(c,MakeSymbol(attr),get,set); } static void AddAttrib(t_classid c,const char *attr,bool (*get)(flext_base *,AtomAnything *&),bool (*set)(flext_base *,AtomAnything *&)) { AddAttrib(c,MakeSymbol(attr),get,set); } //! @} FLEXT_C_CATTR //! Dump an attribute to the attribute outlet bool DumpAttrib(const t_symbol *attr) const; //! Dump an attribute to the attribute outlet bool DumpAttrib(const char *attr) const { return DumpAttrib(MakeSymbol(attr)); } // check for attribute symbol @ static int CheckAttrib(int argc,const t_atom *argv); // check for attribute symbol @ static int CheckAttrib(const AtomList &args,int offset = 0) { return CheckAttrib(args.Count()-offset,args.Atoms()+offset)+offset; } //! List attributes bool ListAttrib() const; //! List attributes void ListAttrib(AtomList &a) const; //! Get an attribute value bool GetAttrib(const t_symbol *s,AtomList &a) const; //! Set an attribute value bool SetAttrib(const t_symbol *s,int argc,const t_atom *argv); //! Set an attribute value bool SetAttrib(const t_symbol *s,const AtomList &a) { return SetAttrib(s,a.Count(),a.Atoms()); } // get and set the attribute bool BangAttrib(const t_symbol *a); // get and set the attribute bool BangAttrib(const char *a) { return BangAttrib(MakeSymbol(a)); } // get and set all (both get- and settables) bool BangAttribAll(); // show/hide the attribute bool ShowAttrib(const t_symbol *a,bool show) const; // show/hide the attribute bool ShowAttrib(const char *a,bool show) { return ShowAttrib(MakeSymbol(a),show); } //! List methods void ListMethods(AtomList &a,int inlet = 0) const; /*! \addtogroup FLEXT_C_INOUT @{ */ //! \brief get a code for a list of inlets or outlets unsigned long XletCode(int tp = xlet_none,...); // end list with 0 (= tp_none) !! /*! \brief Add some inlets by a special code representing the types \remark use XletCode function to get code value */ void AddInlets(unsigned long code); //! \brief Add one or more inlet(s) void AddInlet(int tp,int mult = 1,const char *desc = NULL); /*! \brief Add some inlets by a special code representing the types \remark use XletCode function to get code value */ void AddOutlets(unsigned long code); //! \brief Add one or more outlet(s) void AddOutlet(int tp,int mult = 1,const char *desc = NULL); //! \brief Set the description of an indexed inlet void DescInlet(int ix,const char *desc); //! \brief Set the description of an indexed outlet void DescOutlet(int ix,const char *desc); //! @} FLEXT_C_INOUT // method handling public: class AttrItem; class Item { public: Item(AttrItem *a): attr(a),nxt(NULL) {} virtual ~Item(); bool IsAttr() const { return attr != NULL; } AttrItem *attr; Item *nxt; }; typedef TablePtrMap TablePtrMapDef; class ItemSet :public TablePtrMapDef { public: virtual ~ItemSet(); virtual void clear(); }; /*! This class holds hashed item entries \note not thread-safe! */ class FLEXT_SHARE ItemCont { public: ItemCont(); ~ItemCont(); int Min() const { return -1; } int Max() const { return size-2; } bool Contained(int i) const { return i+1 < size; } //! Add an entry void Add(Item *it,const t_symbol *tag,int inlet = 0); //! Remove an entry bool Remove(Item *it,const t_symbol *tag,int inlet,bool free); //! Find an entry list in the Item array Item *FindList(const t_symbol *tag,int inlet = 0); //! Get list for an inlet ItemSet &GetInlet(int inlet = 0) { FLEXT_ASSERT(inlet >= Min() && inlet <= Max()); return *cont[inlet+1]; } //! Get counter for total members (for index of new item) int Members() const { return members; } protected: void Resize(int nsz); int members; int memsize,size; ItemSet **cont; }; //! \brief This represents an item of the method list class MethItem: public Item { public: MethItem(AttrItem *conn = NULL); virtual ~MethItem(); void SetArgs(methfun fun,int argc,int *args); int index; int argc; int *args; methfun fun; }; //! \brief This represents an item of the attribute list class AttrItem: public Item { public: AttrItem(const t_symbol *tag,int tp,methfun fun,int flags); enum { afl_get = 0x01, afl_set = 0x02, afl_getset = afl_get|afl_set, afl_shown = 0x08 }; bool IsGet() const { return (flags&afl_getset) == afl_get; } bool IsSet() const { return (flags&afl_getset) == afl_set; } bool IsShown() const { return (flags&afl_shown) != 0; } bool BothExist() const { return counter != NULL; } AttrItem *Counterpart() { return counter; } int index; int flags; int argtp; methfun fun; AttrItem *counter; const t_symbol *tag; }; //! Represent a data value of an attribute class AttrData: public flext_root { public: AttrData(): flags(0) {} enum { afl_save = 0x01,afl_init = 0x02,afl_inited = 0x04 }; void SetSave(bool s) { if(s) flags |= afl_save; else flags &= ~afl_save; } bool IsSaved() const { return (flags&afl_save) != 0; } void SetInit(bool s) { if(s) flags |= afl_init; else flags &= ~afl_init; } bool IsInit() const { return (flags&afl_init) != 0; } void SetInitValue(int argc,const t_atom *argv) { init(argc,argv); flags |= afl_inited; } void SetInitValue(const AtomList &l) { SetInitValue(l.Count(),l.Atoms()); } bool IsInitValue() const { return (flags&afl_inited) != 0; } const AtomList &GetInitValue() const { return init; } AtomList init; int flags; }; class AttrDataCont :public TablePtrMap { public: virtual ~AttrDataCont(); virtual void clear(); }; // these outlet functions don't check for thread but send directly to the real-time system void ToSysBang(int n) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_bang((t_outlet *)o); CRITOFF(); } } void ToSysFloat(int n,float f) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_float((t_outlet *)o,f); CRITOFF(); } } void ToSysInt(int n,int f) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_flint((t_outlet *)o,f); CRITOFF(); } } void ToSysSymbol(int n,const t_symbol *s) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_symbol((t_outlet *)o,const_cast(s)); CRITOFF(); } } void ToSysString(int n,const char *s) const { ToSysSymbol(n,MakeSymbol(s)); } void ToSysList(int n,int argc,const t_atom *argv) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_list((t_outlet *)o,const_cast(sym_list),argc,(t_atom *)argv); CRITOFF(); } } void ToSysList(int n,const AtomList &list) const { ToSysList(n,list.Count(),list.Atoms()); } void ToSysAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_anything((t_outlet *)o,const_cast(s),argc,(t_atom *)argv); CRITOFF(); } } void ToSysAnything(int n,const AtomAnything &any) const { ToSysAnything(n,any.Header(),any.Count(),any.Atoms()); } void ToSysAnything(int n,const t_symbol *s,const AtomList &list) const { ToSysAnything(n,s,list.Count(),list.Atoms()); } void ToSysBool(int n,bool f) const { ToSysInt(n,f?1:0); } void ToSysAtom(int n,const t_atom &at) const; void ToSysDouble(int n,double d) const { t_atom dbl[2]; ToSysList(n,2,SetDouble(dbl,d)); } static void ToSysMsg(MsgBundle *mb); // add class method handlers static void AddMessageMethods(t_class *c,bool dsp,bool dspin); private: class pxbnd_object; public: //! \brief This represents an item of the symbol-bound method list class BindItem: public Item { public: BindItem(bool (*f)(flext_base *,t_symbol *s,int,t_atom *,void *),pxbnd_object *px); virtual ~BindItem(); void Unbind(const t_symbol *s); bool (*fun)(flext_base *,t_symbol *s,int,t_atom *,void *); pxbnd_object *px; }; ItemCont *ThMeths() { if(!methhead) methhead = new ItemCont; return methhead; } static ItemCont *ClMeths(t_classid c); //! \brief This is the central function to add message handlers. It is used by all other AddMethod incarnations. static void AddMethod(ItemCont *ma,int inlet,const t_symbol *tag,methfun fun,int tp,...); ItemCont *ThAttrs() { return attrhead; } static ItemCont *ClAttrs(t_classid c); static void AddAttrib(ItemCont *aa,ItemCont *ma,const t_symbol *attr,int tp,methfun gfun,methfun sfun); void AddAttrib(const t_symbol *attr,int tp,methfun gfun,methfun sfun); static void AddAttrib(t_classid c,const t_symbol *attr,int tp,methfun gfun,methfun sfun); private: static inline flext_base *thisObject(flext_hdr *c) { return FLEXT_CAST(c->data); } static void Setup(t_classid c); //! \brief This represents either an inlet or outlet during construction class FLEXT_SHARE xlet { public: xlet(); ~xlet(); int tp; char *desc; void Desc(const char *c); }; static xlet inlist[]; static xlet outlist[]; //! current message tag static const t_symbol *curtag; //! number of message and signal inlets/outlets unsigned char incnt,outcnt,insigs,outsigs; outlet **outlets; union t_any { float ft; int it; bool bt; const t_symbol *st; #if FLEXT_SYS == FLEXT_SYS_PD t_gpointer *pt; #endif void *vt; }; typedef bool (*methfun_V)(flext_base *c,int argc,t_atom *argv); typedef bool (*methfun_A)(flext_base *c,const t_symbol *s,int argc,t_atom *argv); typedef bool (*methfun_0)(flext_base *c); typedef bool (*methfun_1)(flext_base *c,t_any &); typedef bool (*methfun_2)(flext_base *c,t_any &,t_any &); typedef bool (*methfun_3)(flext_base *c,t_any &,t_any &,t_any &); typedef bool (*methfun_4)(flext_base *c,t_any &,t_any &,t_any &,t_any &); typedef bool (*methfun_5)(flext_base *c,t_any &,t_any &,t_any &,t_any &,t_any &); mutable ItemCont *methhead; mutable ItemCont *bindhead; bool FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *argv); bool FindMethAny(int inlet,const t_symbol *s,int argc,const t_atom *argv); bool TryMethTag(Item *lst,const t_symbol *tag,int argc,const t_atom *argv); bool TryMethSym(Item *lst,const t_symbol *s); bool TryMethAny(Item *lst,const t_symbol *s,int argc,const t_atom *argv); mutable ItemCont *attrhead; mutable AttrDataCont *attrdata; AttrItem *FindAttrib(const t_symbol *tag,bool get,bool msg = false) const; bool InitAttrib(int argc,const t_atom *argv); bool DumpAttrib(const t_symbol *tag,AttrItem *a) const; bool GetAttrib(const t_symbol *tag,AttrItem *a,AtomList &l) const; bool SetAttrib(const t_symbol *tag,AttrItem *a,int argc,const t_atom *argv); bool SetAttrib(const t_symbol *tag,AttrItem *a,const AtomList &l) { return SetAttrib(tag,a,l.Count(),l.Atoms()); } // get and set the attribute bool BangAttrib(const t_symbol *tag,AttrItem *a); // show/hide the attribute bool ShowAttrib(AttrItem *a,bool show) const; static bool cb_ListMethods(flext_base *c,int argc,const t_atom *argv); static bool cb_ListAttrib(flext_base *c) { Locker lock(c); return c->ListAttrib(); } // queue stuff //! Start message queue static void StartQueue(); #if FLEXT_QMODE == 2 //! Queue worker function static void QWorker(thr_params *); #endif //! Flush messages in the queue static void QFlush(flext_base *th = NULL); static bool qustarted; #if FLEXT_SYS == FLEXT_SYS_PD static void SetGfx(t_classid c); #ifndef FLEXT_NOATTREDIT // attribute editor static bool cb_AttrDialog(flext_base *c,int argc,const t_atom *argv); static void cb_GfxProperties(flext_hdr *c, t_glist *); #endif #ifdef FLEXT_ATTRHIDE static void cb_GfxVis(flext_hdr *c, t_glist *gl, int vis); static void cb_GfxSave(flext_hdr *c, t_binbuf *b); static void cb_GfxSelect(flext_hdr *x, struct _glist *glist, int state); void BinbufArgs(t_binbuf *b,t_binbuf *args,bool withname,bool transdoll); void BinbufAttr(t_binbuf *b,bool transdoll); #endif static void cb_bang(flext_hdr *c); static void cb_float(flext_hdr *c,t_float f); static void cb_symbol(flext_hdr *c,const t_symbol *s); // static void cb_pointer(fltext_hdr *c,const t_gpointer *p); static void cb_anything(flext_hdr *c,const t_symbol *s,int argc,t_atom *argv); // proxy object (for additional inlets) static t_class *px_class; struct px_object // no virtual table! { t_object obj; // MUST reside at memory offset 0 flext_base *base; int index; void init(flext_base *b,int ix) { base = b; index = ix; } static void px_bang(px_object *c); static void px_float(px_object *c,t_float f); static void px_symbol(px_object *c,const t_symbol *s); // static void px_pointer(px_object *c,const t_gpointer *p); static void px_anything(px_object *c,const t_symbol *s,int argc,t_atom *argv); }; static void cb_px_ft1(flext_hdr *c,t_float f); static void cb_px_ft2(flext_hdr *c,t_float f); static void cb_px_ft3(flext_hdr *c,t_float f); static void cb_px_ft4(flext_hdr *c,t_float f); static void cb_px_ft5(flext_hdr *c,t_float f); static void cb_px_ft6(flext_hdr *c,t_float f); static void cb_px_ft7(flext_hdr *c,t_float f); static void cb_px_ft8(flext_hdr *c,t_float f); static void cb_px_ft9(flext_hdr *c,t_float f); #elif FLEXT_SYS == FLEXT_SYS_MAX typedef t_object px_object; static void cb_bang(flext_hdr *c); static void cb_float(flext_hdr *c,double f); static void cb_int(flext_hdr *c,long v); static void cb_anything(flext_hdr *c,const t_symbol *s,short argc,t_atom *argv); static void cb_px_in1(flext_hdr *c,long v); static void cb_px_in2(flext_hdr *c,long v); static void cb_px_in3(flext_hdr *c,long v); static void cb_px_in4(flext_hdr *c,long v); static void cb_px_in5(flext_hdr *c,long v); static void cb_px_in6(flext_hdr *c,long v); static void cb_px_in7(flext_hdr *c,long v); static void cb_px_in8(flext_hdr *c,long v); static void cb_px_in9(flext_hdr *c,long v); static void cb_px_ft1(flext_hdr *c,double f); static void cb_px_ft2(flext_hdr *c,double f); static void cb_px_ft3(flext_hdr *c,double f); static void cb_px_ft4(flext_hdr *c,double f); static void cb_px_ft5(flext_hdr *c,double f); static void cb_px_ft6(flext_hdr *c,double f); static void cb_px_ft7(flext_hdr *c,double f); static void cb_px_ft8(flext_hdr *c,double f); static void cb_px_ft9(flext_hdr *c,double f); #endif px_object **inlets; // --------- symbol-bound proxy static t_class *pxbnd_class; class pxbnd_object: public flext_root // no virtual table! { public: t_object obj; // MUST reside at memory offset 0 flext_base *base; BindItem *item; void *data; void init(flext_base *b,BindItem *it,void *d) { base = b; item = it; data = d; } static void px_method(pxbnd_object *c,const t_symbol *s,int argc,t_atom *argv); }; //! create proxy class for symbol binding static void SetupBindProxy(); // --------- //! set up inlet proxies static void SetProxies(t_class *c,bool dsp); //! initialize inlets (according to class or object constructor definitions) bool InitInlets(); //! initialize outlets (according to class or object constructor definitions) bool InitOutlets(); // callback functions static void cb_loadbang(flext_hdr *c); #if FLEXT_SYS == FLEXT_SYS_MAX char **indesc,**outdesc; static void cb_assist(flext_hdr *c,void *b,long msg,long arg,char *s); typedef void *Point; static void cb_click (flext_hdr *c, Point pt, short mods); #if MSP64 static void cb_dsp64(flext_hdr *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags); #else static void cb_dsp(flext_hdr *c,t_signal **s,short *count); #endif #elif FLEXT_SYS == FLEXT_SYS_PD static void cb_click(flext_hdr *z,t_floatarg xpos,t_floatarg ypos,t_floatarg shift,t_floatarg ctrl,t_floatarg alt); static void cb_dsp(flext_hdr *c,t_signal **s); #endif }; #include "flpopns.h" #endif flext-0-6-3/source/flcontainers.h000066400000000000000000000062041446466241400170150ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flcontainers.h \brief Lock-free container classes */ #ifndef __FLCONTAINERS_H #define __FLCONTAINERS_H #include "flprefix.h" #include "lockfree/stack.hpp" #include "lockfree/fifo.hpp" #include "flpushns.h" class LifoCell: public lockfree::stack_node {}; class Lifo : public lockfree::intrusive_stack { public: inline void Push(LifoCell *cell) { this->push(cell); } inline LifoCell *Pop() { return this->pop(); } inline bool Avail() const { return !this->empty(); } }; template class TypedLifo : public Lifo { public: inline void Push(T *c) { Lifo::Push(static_cast(c)); } inline T *Pop() { return static_cast(Lifo::Pop()); } }; template class ValueLifoCell : public LifoCell { public: ValueLifoCell(T v): value(v) {} T value; }; template class ValueLifo : public TypedLifo > { public: inline void Push(T v) { TypedLifo >::Push(new ValueLifoCell(v)); } inline T Pop() { ValueLifoCell *p = TypedLifo >::Pop(); T v = p->value; delete p; return v; } }; template class PooledLifo : public TypedLifo { public: PooledLifo(): sz(0),resz(0) {} void Push(T *c) { TypedLifo::Push(c); ++sz; } T *Pop() { T *r = TypedLifo::Pop(); if(r) --sz; return r; } T *New() { T *n = reuse.Pop(); if(n) { --resz; return n; } else return new T; } inline void Free(T *p) { if(resz < sz*M+O) { reuse.Push(p); ++resz; } else delete p; } private: TypedLifo reuse; size_t sz,resz; }; class FifoCell: public lockfree::fifo_node {}; class Fifo : public lockfree::intrusive_fifo { public: inline void Put(FifoCell *cl) { this->enqueue(cl); } inline FifoCell *Get() { return this->dequeue(); } inline bool Avail() const { return !this->empty(); } }; template class TypedFifo : public Fifo { public: inline void Put(T *c) { Fifo::Put(static_cast(c)); } inline T *Get() { return static_cast(Fifo::Get()); } }; template class ValueFifoCell : public FifoCell { public: ValueFifoCell(T v): value(v) {} T value; }; template class ValueFifo : public TypedFifo > { public: inline void Put(T v) { TypedFifo >::Put(new ValueFifoCell(v)); } inline T Get() { ValueFifoCell *p = TypedFifo >::Get(); T v = p->value; delete p; return v; } }; template class PooledFifo : public TypedFifo { public: ~PooledFifo() { T *n; while((n = reuse.Get()) != NULL) delete n; } inline T *New() { T *n = reuse.Get(); return n?n:new T; } inline void Free(T *p) { if(resz < sz*M+O) reuse.Put(p); else delete p; } private: TypedFifo reuse; size_t sz,resz; }; #include "flpopns.h" #endif flext-0-6-3/source/fldefs.h000066400000000000000000000026061446466241400155730ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs.h \brief This file includes all the #define header files */ #ifndef __FLEXT_DEFS_H #define __FLEXT_DEFS_H /*! \defgroup FLEXT_DEFS Definitions for basic flext functionality @{ */ /*! \brief Switch for compilation of derived virtual classes \remark These need dynamic type casts (and RTTI, naturally) \ingroup FLEXT_GLOBALS */ #ifdef FLEXT_VIRT #define FLEXT_CAST dynamic_cast #else #define FLEXT_CAST static_cast #endif //! @} FLEXT_DEFS #include "fldefs_hdr.h" #include "fldefs_setup.h" // ==================================================================================== /*! \defgroup FLEXT_D_METHOD Declarations for flext methods @{ */ #include "fldefs_methcb.h" #include "fldefs_meththr.h" #include "fldefs_methadd.h" #include "fldefs_methbind.h" #include "fldefs_methcall.h" //! @} FLEXT_D_METHOD #ifdef FLEXT_ATTRIBUTES /*! \defgroup FLEXT_D_ATTRIB Attribute definition \note These have to reside inside the class declaration @{ */ #include "fldefs_attrcb.h" #include "fldefs_attrvar.h" #include "fldefs_attradd.h" //! @} FLEXT_D_ATTRIB #endif // FLEXT_ATTRIBUTES #endif // __FLEXT_DEFS_H flext-0-6-3/source/fldefs_attradd.h000066400000000000000000000100421446466241400172670ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_attradd.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_ATTRADD_H #define __FLEXT_DEFS_ATTRADD_H /*! \defgroup FLEXT_D_CADDATTR Announce object attributes at class scope \ingroup FLEXT_D_ATTRIB \note These can only be used at class construction time @{ */ //! Add handler for a gettable attribute #define FLEXT_CADDATTR_GET(CL,NAME,GFUN) \ \ flext_base::AddAttrib(CL,flext::MakeSymbol(NAME),(FLEXT_GET_PRE(GFUN)),NULL) //! Add handler for a settable attribute #define FLEXT_CADDATTR_SET(CL,NAME,SFUN) \ \ flext_base::AddAttrib(CL,flext::MakeSymbol(NAME),NULL,(FLEXT_SET_PRE(SFUN))) //! Add handlers for a both get- and settable attribute #define FLEXT_CADDATTR_VAR(CL,NAME,GFUN,SFUN) \ \ flext_base::AddAttrib(CL,flext::MakeSymbol(NAME),(FLEXT_GET_PRE(GFUN)),(FLEXT_SET_PRE(SFUN))) //! Add handlers for a both get- and settable attribute #define FLEXT_CADDATTR_VAR1(CL,NAME,FUN) \ \ flext_base::AddAttrib(CL,flext::MakeSymbol(NAME),(FLEXT_GET_PRE(FUN)),(FLEXT_SET_PRE(FUN))) //! Add handler for a gettable enum attribute #define FLEXT_CADDATTR_GET_E(CL,NAME,GFUN) \ \ flext_base::AddAttrib(CL,flext::MakeSymbol(NAME),(bool (*)(flext_base *,int &))(FLEXT_GET_PRE(GFUN)),NULL) //! Add handler for a settable enum attribute #define FLEXT_CADDATTR_SET_E(CL,NAME,SFUN) \ \ flext_base::AddAttrib(CL,flext::MakeSymbol(NAME),NULL,(bool (*)(flext_base *,int &))(FLEXT_SET_PRE(SFUN))) //! Add handlers for a both get- and settable enum attribute #define FLEXT_CADDATTR_VAR_E(CL,NAME,GFUN,SFUN) \ \ flext_base::AddAttrib(CL,flext::MakeSymbol(NAME),(bool (*)(flext_base *,int &))(FLEXT_GET_PRE(GFUN)),(bool (*)(flext_base *,int &))(FLEXT_SET_PRE(SFUN))) //! Add handlers for a both get- and settable enum attribute #define FLEXT_CADDATTR_VAR1_E(CL,NAME,FUN) \ \ flext_base::AddAttrib(CL,flext::MakeSymbol(NAME),(bool (*)(flext_base *,int &))(FLEXT_GET_PRE(FUN)),(bool (*)(flext_base *,int &))(FLEXT_SET_PRE(FUN))) //! @} FLEXT_D_CADDATTR /*! \defgroup FLEXT_D_ADDATTR Announce object attributes \ingroup FLEXT_D_ATTRIB \note These can only be used at object construction time \note (in constructor or in Init() function before call to parent's Init()) @{ */ //! Add handler for a gettable attribute #define FLEXT_ADDATTR_GET(NAME,GFUN) \ \ flext_base::AddAttrib(flext::MakeSymbol(NAME),(FLEXT_GET_PRE(GFUN)),NULL) //! Add handler for a settable attribute #define FLEXT_ADDATTR_SET(NAME,SFUN) \ \ flext_base::AddAttrib(flext::MakeSymbol(NAME),NULL,(FLEXT_SET_PRE(SFUN))) //! Add handlers for a both get- and settable attribute #define FLEXT_ADDATTR_VAR(NAME,GFUN,SFUN) \ \ flext_base::AddAttrib(flext::MakeSymbol(NAME),(FLEXT_GET_PRE(GFUN)),(FLEXT_SET_PRE(SFUN))) //! Add handlers for a both get- and settable attribute #define FLEXT_ADDATTR_VAR1(NAME,FUN) \ \ flext_base::AddAttrib(flext::MakeSymbol(NAME),(FLEXT_GET_PRE(FUN)),(FLEXT_SET_PRE(FUN))) //! Add handler for a gettable enum attribute #define FLEXT_ADDATTR_GET_E(NAME,GFUN) \ \ flext_base::AddAttrib(flext::MakeSymbol(NAME),(bool (*)(flext_base *,int &))(FLEXT_GET_PRE(GFUN)),NULL) //! Add handler for a settable enum attribute #define FLEXT_ADDATTR_SET_E(NAME,SFUN) \ \ flext_base::AddAttrib(flext::MakeSymbol(NAME),NULL,(bool (*)(flext_base *,int &))(FLEXT_SET_PRE(SFUN))) //! Add handlers for a both get- and settable enum attribute #define FLEXT_ADDATTR_VAR_E(NAME,GFUN,SFUN) \ \ flext_base::AddAttrib(flext::MakeSymbol(NAME),(bool (*)(flext_base *,int &))(FLEXT_GET_PRE(GFUN)),(bool (*)(flext_base *,int &))(FLEXT_SET_PRE(SFUN))) //! Add handlers for a both get- and settable enum attribute #define FLEXT_ADDATTR_VAR1_E(NAME,FUN) \ \ flext_base::AddAttrib(flext::MakeSymbol(NAME),(bool (*)(flext_base *,int &))(FLEXT_GET_PRE(FUN)),(bool (*)(flext_base *,int &))(FLEXT_SET_PRE(FUN))) //! @} FLEXT_D_ADDATTR #endif flext-0-6-3/source/fldefs_attrcb.h000066400000000000000000000100631446466241400171260ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_attrcb.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_ATTRCB_H #define __FLEXT_DEFS_ATTRCB_H /*! \brief Declare a attribute set function \internal */ #define FLEXT_CALLSET_(FUN,TP) \ static bool FLEXT_SET_PRE(FUN)(flext_base *c,TP &arg) \ { FLEXT_CAST(c)->FUN(arg); return true; } /*! \brief Declare a attribute get function \internal */ #define FLEXT_CALLGET_(FUN,TP) \ static bool FLEXT_GET_PRE(FUN)(flext_base *c,TP &arg) \ { FLEXT_CAST(c)->FUN(arg); return true; } /*! \defgroup FLEXT_DA_CALLSET Definition of attribute set handlers \ingroup FLEXT_D_ATTRIB @{ */ //! Declare a set function for a float attribute #define FLEXT_CALLSET_F(SFUN) \ \ FLEXT_CALLSET_(SFUN,float) //! Declare a set function for an integer attribute #define FLEXT_CALLSET_I(SFUN) \ \ FLEXT_CALLSET_(SFUN,int) //! Declare a set function for a boolean attribute #define FLEXT_CALLSET_B(SFUN) \ \ FLEXT_CALLSET_(SFUN,bool) /* static bool FLEXT_SET_PRE(FUN)(flext_base *c,int &arg) \ { bool b = arg != 0; FLEXT_CAST(c)->FUN(b); return true; } */ //! Declare a set function for an enum attribute #define FLEXT_CALLSET_E(SFUN,TP) \ \ FLEXT_CALLSET_(SFUN,TP) //! Declare a set function for a symbol attribute #define FLEXT_CALLSET_S(FUN) \ static bool FLEXT_SET_PRE(FUN)(flext_base *c,const t_symbol *&arg) \ { FLEXT_CAST(c)->FUN(arg); return true; } //! Declare a set function for a variable list attribute #define FLEXT_CALLSET_V(FUN) \ static bool FLEXT_SET_PRE(FUN)(flext_base *c,flext::AtomList *&arg) \ { FLEXT_CAST(c)->FUN(*arg); return true; } //! @} FLEXT_DA_CALLSET /*! \defgroup FLEXT_DA_CALLGET Definition of attribute get handlers \ingroup FLEXT_D_ATTRIB @{ */ //! Declare a get function for a float attribute #define FLEXT_CALLGET_F(GFUN) \ \ FLEXT_CALLGET_(GFUN,float) //! Declare a get function for an integer attribute #define FLEXT_CALLGET_I(GFUN) \ \ FLEXT_CALLGET_(GFUN,int) //! Declare a get function for a boolean attribute #define FLEXT_CALLGET_B(GFUN) \ \ FLEXT_CALLGET_(GFUN,bool) /* static bool FLEXT_GET_PRE(FUN)(flext_base *c,int &arg) \ { bool b; FLEXT_CAST(c)->FUN(b); arg = b?1:0; return true; } */ //! Declare a get function for an enum attribute #define FLEXT_CALLGET_E(GFUN,TP) \ \ FLEXT_CALLGET_(GFUN,TP) //! Declare a get function for a symbol attribute #define FLEXT_CALLGET_S(FUN) \ static bool FLEXT_GET_PRE(FUN)(flext_base *c,const t_symbol *&arg) \ { FLEXT_CAST(c)->FUN(arg); return true; } //! Declare a get function for a variable list attribute #define FLEXT_CALLGET_V(FUN) \ static bool FLEXT_GET_PRE(FUN)(flext_base *c,flext::AtomList *&arg) \ { FLEXT_CAST(c)->FUN(*arg); return true; } //! @} FLEXT_DA_CALLGET /*! \defgroup FLEXT_DA_CALLVAR Definition of attribute transfer handlers (both get and set) \ingroup FLEXT_D_ATTRIB @{ */ //! Declare both get and set functions for a float attribute #define FLEXT_CALLVAR_F(GFUN,SFUN) \ \ FLEXT_CALLGET_F(GFUN) FLEXT_CALLSET_F(SFUN) //! Declare both get and set functions for an integer attribute #define FLEXT_CALLVAR_I(GFUN,SFUN) \ \ FLEXT_CALLGET_I(GFUN) FLEXT_CALLSET_I(SFUN) //! Declare both get and set functions for a symbol attribute #define FLEXT_CALLVAR_S(GFUN,SFUN) \ \ FLEXT_CALLGET_S(GFUN) FLEXT_CALLSET_S(SFUN) //! Declare both get and set functions for a boolean attribute #define FLEXT_CALLVAR_B(GFUN,SFUN) \ \ FLEXT_CALLGET_B(GFUN) FLEXT_CALLSET_B(SFUN) //! Declare both get and set functions for an enum attribute #define FLEXT_CALLVAR_E(GFUN,SFUN,TP) \ \ FLEXT_CALLGET_E(GFUN,TP) FLEXT_CALLSET_E(SFUN,TP) //! Declare both get and set functions for a variable list attribute #define FLEXT_CALLVAR_V(GFUN,SFUN) \ \ FLEXT_CALLGET_V(GFUN) FLEXT_CALLSET_V(SFUN) //! @} FLEXT_DA_CALLVAR #endif flext-0-6-3/source/fldefs_attrvar.h000066400000000000000000000100211446466241400173240ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_attrvar.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_ATTRVAR_H #define __FLEXT_DEFS_ATTRVAR_H /*! \brief Declare an implicit attribute set function \internal */ #define FLEXT_ATTRSET_(VAR,TP) \ static bool FLEXT_SET_PRE(VAR)(flext_base *c,TP &arg) \ { FLEXT_CAST(c)->VAR = arg; return true; } /*! \brief Declare an implicit attribute get function \internal */ #define FLEXT_ATTRGET_(VAR,TP) \ static bool FLEXT_GET_PRE(VAR)(flext_base *c,TP &arg) \ { arg = (TP)FLEXT_CAST(c)->VAR; return true; } /*! \defgroup FLEXT_DA_ATTRSET Definition of implicit attribute set handlers \ingroup FLEXT_D_ATTRIB @{ */ //! Declare an implicit set function for a float attribute #define FLEXT_ATTRSET_F(VAR) \ \ FLEXT_ATTRSET_(VAR,float) //! Declare an implicit set function for an integer attribute #define FLEXT_ATTRSET_I(VAR) \ \ FLEXT_ATTRSET_(VAR,int) //! Declare an implicit set function for a symbol attribute #define FLEXT_ATTRSET_S(VAR) \ \ FLEXT_ATTRSET_(VAR,const t_symbol *) //! Declare an implicit set function for a boolean attribute #define FLEXT_ATTRSET_B(VAR) \ \ FLEXT_ATTRSET_(VAR,bool) /* static bool FLEXT_SET_PRE(VAR)(flext_base *c,int &arg) \ { FLEXT_CAST(c)->VAR = arg != 0; return true; } */ //! Declare an implicit set function for an enum attribute #define FLEXT_ATTRSET_E(VAR,TP) \ \ FLEXT_ATTRSET_(VAR,TP) //! Declare an implicit set function for a variable list attribute #define FLEXT_ATTRSET_V(VAR) \ static bool FLEXT_SET_PRE(VAR)(flext_base *c,flext::AtomList *&arg) \ { FLEXT_CAST(c)->VAR = *arg; return true; } //! @} FLEXT_DA_ATTRSET /*! \defgroup FLEXT_DA_ATTRGET Definition of implicit attribute get handlers \ingroup FLEXT_D_ATTRIB @{ */ //! Declare an implicit get function for a float attribute #define FLEXT_ATTRGET_F(VAR) \ \ FLEXT_ATTRGET_(VAR,float) //! Declare an implicit get function for an integer attribute #define FLEXT_ATTRGET_I(VAR) \ \ FLEXT_ATTRGET_(VAR,int) //! Declare an implicit get function for a symbol attribute #define FLEXT_ATTRGET_S(VAR) \ \ FLEXT_ATTRGET_(VAR,const t_symbol *) //! Declare an implicit get function for a boolean attribute #define FLEXT_ATTRGET_B(VAR) \ \ FLEXT_ATTRGET_(VAR,bool) /* static bool FLEXT_GET_PRE(VAR)(flext_base *c,int &arg) \ { arg = FLEXT_CAST(c)->VAR?1:0; return true; } */ //! Declare an implicit get function for an enum attribute #define FLEXT_ATTRGET_E(VAR,TP) \ \ FLEXT_ATTRGET_(VAR,TP) //! Declare an implicit get function for a variable list attribute #define FLEXT_ATTRGET_V(VAR) \ static bool FLEXT_GET_PRE(VAR)(flext_base *c,AtomList *&arg) \ { *arg = FLEXT_CAST(c)->VAR; return true; } //! @} FLEXT_DA_ATTRGET /*! \defgroup FLEXT_DA_ATTRVAR Definition of implicit attribute transfer handlers (both get and set) \ingroup FLEXT_D_ATTRIB @{ */ //! Declare both implicit get and set functions for a float attribute #define FLEXT_ATTRVAR_F(VAR) \ \ FLEXT_ATTRGET_F(VAR) FLEXT_ATTRSET_F(VAR) //! Declare both implicit get and set functions for an integer attribute #define FLEXT_ATTRVAR_I(VAR) \ \ FLEXT_ATTRGET_I(VAR) FLEXT_ATTRSET_I(VAR) //! Declare both implicit get and set functions for a symbol attribute #define FLEXT_ATTRVAR_S(VAR) \ \ FLEXT_ATTRGET_S(VAR) FLEXT_ATTRSET_S(VAR) //! Declare both implicit get and set functions for a boolean attribute #define FLEXT_ATTRVAR_B(VAR) \ \ FLEXT_ATTRGET_B(VAR) FLEXT_ATTRSET_B(VAR) //! Declare both implicit get and set functions for an enum attribute #define FLEXT_ATTRVAR_E(VAR,TP) \ \ FLEXT_ATTRGET_(VAR,TP) FLEXT_ATTRSET_(VAR,TP) //! Declare both implicit get and set functions for a variable list attribute #define FLEXT_ATTRVAR_V(VAR) \ \ FLEXT_ATTRGET_V(VAR) FLEXT_ATTRSET_V(VAR) //! @} FLEXT_DA_ATTRVAR #endif flext-0-6-3/source/fldefs_hdr.h000066400000000000000000000035121446466241400164250ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_hdr.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_HEADER_H #define __FLEXT_DEFS_HEADER_H /*! \defgroup FLEXT_D_HEADER Flext class header \note One (and only one!) of these definitions is compulsory for the class declaration. \note It has to be placed somewhere in the class definition (not necessarily in a public section). @{ */ /*! \brief Plain flext class header \param NEW_CLASS name of the current C++ class \param PARENT_CLASS name of the base C++ class (e.g. flext_base or flext_dsp) */ #define FLEXT_HEADER(NEW_CLASS,PARENT_CLASS) \ \ FLEXT_REALHDR(NEW_CLASS, PARENT_CLASS) #define FLEXT_HEADER_T(NEW_CLASS,PARENT_CLASS) \ \ FLEXT_REALHDR_T(NEW_CLASS, PARENT_CLASS) /*! \brief Flext class header with setup function \param NEW_CLASS name of the current C++ class \param PARENT_CLASS name of the base C++ class (e.g. flext_base or flext_dsp) \param SETUPFUN setup function, of type "void (*setupfn)(t_class *)" The setup function is called after class creation. It corresponds to the original PD "[object]_setup" function, apart from the fact that all necessary class initializations have already been taken care of by flext. The setup function can e.g. be used for a message to the console upon first creation of an object. */ #define FLEXT_HEADER_S(NEW_CLASS, PARENT_CLASS, SETUPFUN)\ \ FLEXT_REALHDR_S(NEW_CLASS, PARENT_CLASS, SETUPFUN) #define FLEXT_HEADER_TS(NEW_CLASS, PARENT_CLASS, SETUPFUN)\ \ FLEXT_REALHDR_TS(NEW_CLASS, PARENT_CLASS, SETUPFUN) //! @} FLEXT_D_HEADER #endif flext-0-6-3/source/fldefs_methadd.h000066400000000000000000000200421446466241400172530ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_methadd.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_METHADD_H #define __FLEXT_DEFS_METHADD_H /*! \defgroup FLEXT_D_CADDMETHOD Add flext methods within class scope \ingroup FLEXT_D_METHOD \note These can only be used at class construction time @{ */ /*! Add a method handler for bang \note This is for compatibility - better use the method below */ #define FLEXT_CADDBANG(CL,IX,M_FUN) \ \ flext_base::AddMethod(CL,IX,FLEXT_CALL_PRE(M_FUN)) //! Add a handler for a method with either no, list or anything arguments #define FLEXT_CADDMETHOD(CL,IX,M_FUN) \ \ flext_base::AddMethod(CL,IX,FLEXT_CALL_PRE(M_FUN)) //! Add a a handler for a method with implicit arguments #define FLEXT_CADDMETHOD_(CL,IX,M_TAG,M_FUN) \ \ flext_base::AddMethod(CL,IX,flext::MakeSymbol(M_TAG),FLEXT_CALL_PRE(M_FUN)) //! Add a handler for a method with 1 enum type argument #define FLEXT_CADDMETHOD_E(CL,IX,M_TAG,M_FUN) \ \ flext_base::AddMethod(ClMeths(CL),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),a_int,a_null) //! Add a handler for a method with 1 argument #define FLEXT_CADDMETHOD_1(CL,IX,M_TAG,M_FUN,TP1) \ \ flext_base::AddMethod(ClMeths(CL),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),a_null) //! Add a handler for a method with 2 arguments #define FLEXT_CADDMETHOD_2(CL,IX,M_TAG,M_FUN,TP1,TP2) \ \ flext_base::AddMethod(ClMeths(CL),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),FLEXTARG(TP2),a_null) //! Add a handler for a method with 3 arguments #define FLEXT_CADDMETHOD_3(CL,IX,M_TAG,M_FUN,TP1,TP2,TP3) \ \ flext_base::AddMethod(ClMeths(CL),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),FLEXTARG(TP2),FLEXTARG(TP3),a_null) //! Add a handler for a method with 4 arguments #define FLEXT_CADDMETHOD_4(CL,IX,M_TAG,M_FUN,TP1,TP2,TP3,TP4) \ \ flext_base::AddMethod(ClMeths(CL),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),FLEXTARG(TP2),FLEXTARG(TP3),FLEXTARG(TP4),a_null) //! Add a handler for a method with 5 arguments #define FLEXT_CADDMETHOD_5(CL,IX,M_TAG,M_FUN,TP1,TP2,TP3,TP4,TP5) \ \ flext_base::AddMethod(ClMeths(CL),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),FLEXTARG(TP2),FLEXTARG(TP3),FLEXTARG(TP4),FLEXTARG(TP5),a_null) // Shortcuts //! Add a handler for a method with a boolean argument #define FLEXT_CADDMETHOD_B(CL,IX,M_TAG,M_FUN) \ \ FLEXT_CADDMETHOD_1(CL,IX,flext::MakeSymbol(M_TAG),M_FUN,bool) //! Add a handler for a method with 1 float argument #define FLEXT_CADDMETHOD_F(CL,IX,M_TAG,M_FUN) \ \ FLEXT_CADDMETHOD_1(CL,IX,flext::MakeSymbol(M_TAG),M_FUN,float) //! Add a handler for a method with 2 float arguments #define FLEXT_CADDMETHOD_FF(CL,IX,M_TAG,M_FUN) \ \ FLEXT_CADDMETHOD_2(CL,IX,flext::MakeSymbol(M_TAG),M_FUN,float,float) //! Add a handler for a method with 3 float arguments #define FLEXT_CADDMETHOD_FFF(CL,IX,M_TAG,M_FUN) \ \ FLEXT_CADDMETHOD_3(CL,IX,flext::MakeSymbol(M_TAG),M_FUN,float,float,float) //! Add a handler for a method with 1 integer argument #define FLEXT_CADDMETHOD_I(CL,IX,M_TAG,M_FUN) \ \ FLEXT_CADDMETHOD_1(CL,IX,flext::MakeSymbol(M_TAG),M_FUN,int) //! Add a handler for a method with 2 integer arguments #define FLEXT_CADDMETHOD_II(CL,IX,M_TAG,M_FUN) \ \ FLEXT_CADDMETHOD_2(CL,IX,flext::MakeSymbol(M_TAG),M_FUN,int,int) //! Add a handler for a method with 3 integer arguments #define FLEXT_CADDMETHOD_III(CL,IX,M_TAG,M_FUN) \ \ FLEXT_CADDMETHOD_3(CL,IX,flext::MakeSymbol(M_TAG),M_FUN,int,int,int) //! @} FLEXT_D_CADDMETHOD /*! \defgroup FLEXT_D_ADDMETHOD Add flext methods \ingroup FLEXT_D_METHOD \note These can only be used at object construction time \note (in constructor or in Init() function before call to parent's Init()) @{ */ //! Set timer callback #define FLEXT_ADDTIMER(TMR,M_FUN) \ \ TMR.SetCallback(*this,FLEXT_CALL_PRE(M_FUN)) //! Enable list element distribution over inlets (if no better handler found) #define FLEXT_ADDDIST() \ \ flext_base::SetDist(true) //! Add a method handler for bang #define FLEXT_ADDBANG(IX,M_FUN) \ \ flext_base::AddMethod(IX,"bang",FLEXT_CALL_PRE(M_FUN)) //! Add a handler for a method with either no, list or anything arguments #define FLEXT_ADDMETHOD(IX,M_FUN) \ \ flext_base::AddMethod(IX,FLEXT_CALL_PRE(M_FUN)) /*! \brief Add a handler for a method with a (variable argument) list \deprecated This definition obscures that _ indicates the usage of a message tag - use FLEXT_ADDMETHOD instead \note This is already covered by FLEXT_ADDMETHOD, but here for the sake of clarity */ #define FLEXT_ADDMETHOD_V(IX,M_FUN) \ \ flext_base::AddMethod(IX,FLEXT_CALL_PRE(M_FUN)) /*! \brief Add a handler for a method with an anything argument \deprecated This definition obscures that _ indicates the usage of a message tag - use FLEXT_ADDMETHOD instead \note This is already covered by FLEXT_ADDMETHOD, but here for the sake of clarity */ #define FLEXT_ADDMETHOD_A(IX,M_FUN) \ \ flext_base::AddMethod(IX,FLEXT_CALL_PRE(M_FUN)) //! Add a a handler for a tagged method with implicit arguments #define FLEXT_ADDMETHOD_(IX,M_TAG,M_FUN) \ \ flext_base::AddMethod(IX,flext::MakeSymbol(M_TAG),FLEXT_CALL_PRE(M_FUN)) //! Add a handler for a method with 1 enum type argument #define FLEXT_ADDMETHOD_E(IX,M_TAG,M_FUN) \ \ flext_base::AddMethod(ThMeths(),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),a_int,a_null) //! Add a handler for a method with 1 argument #define FLEXT_ADDMETHOD_1(IX,M_TAG,M_FUN,TP1) \ \ flext_base::AddMethod(ThMeths(),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),a_null) //! Add a handler for a method with 2 arguments #define FLEXT_ADDMETHOD_2(IX,M_TAG,M_FUN,TP1,TP2) \ \ flext_base::AddMethod(ThMeths(),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),FLEXTARG(TP2),a_null) //! Add a handler for a method with 3 arguments #define FLEXT_ADDMETHOD_3(IX,M_TAG,M_FUN,TP1,TP2,TP3) \ \ flext_base::AddMethod(ThMeths(),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),FLEXTARG(TP2),FLEXTARG(TP3),a_null) //! Add a handler for a method with 4 arguments #define FLEXT_ADDMETHOD_4(IX,M_TAG,M_FUN,TP1,TP2,TP3,TP4) \ \ flext_base::AddMethod(ThMeths(),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),FLEXTARG(TP2),FLEXTARG(TP3),FLEXTARG(TP4),a_null) //! Add a handler for a method with 5 arguments #define FLEXT_ADDMETHOD_5(IX,M_TAG,M_FUN,TP1,TP2,TP3,TP4,TP5) \ \ flext_base::AddMethod(ThMeths(),IX,flext::MakeSymbol(M_TAG),(methfun)(FLEXT_CALL_PRE(M_FUN)),FLEXTARG(TP1),FLEXTARG(TP2),FLEXTARG(TP3),FLEXTARG(TP4),FLEXTARG(TP5),a_null) // Shortcuts //! Add a handler for a method with a boolean argument #define FLEXT_ADDMETHOD_B(IX,M_TAG,M_FUN) \ \ FLEXT_ADDMETHOD_1(IX,flext::MakeSymbol(M_TAG),M_FUN,bool) //! Add a handler for a method with 1 float argument #define FLEXT_ADDMETHOD_F(IX,M_TAG,M_FUN) \ \ FLEXT_ADDMETHOD_1(IX,flext::MakeSymbol(M_TAG),M_FUN,float) //! Add a handler for a method with 2 float arguments #define FLEXT_ADDMETHOD_FF(IX,M_TAG,M_FUN) \ \ FLEXT_ADDMETHOD_2(IX,flext::MakeSymbol(M_TAG),M_FUN,float,float) //! Add a handler for a method with 3 float arguments #define FLEXT_ADDMETHOD_FFF(IX,M_TAG,M_FUN) \ \ FLEXT_ADDMETHOD_3(IX,flext::MakeSymbol(M_TAG),M_FUN,float,float,float) //! Add a handler for a method with 1 integer argument #define FLEXT_ADDMETHOD_I(IX,M_TAG,M_FUN) \ \ FLEXT_ADDMETHOD_1(IX,flext::MakeSymbol(M_TAG),M_FUN,int) //! Add a handler for a method with 2 integer arguments #define FLEXT_ADDMETHOD_II(IX,M_TAG,M_FUN) \ \ FLEXT_ADDMETHOD_2(IX,flext::MakeSymbol(M_TAG),M_FUN,int,int) //! Add a handler for a method with 3 integer arguments #define FLEXT_ADDMETHOD_III(IX,M_TAG,M_FUN) \ \ FLEXT_ADDMETHOD_3(IX,flext::MakeSymbol(M_TAG),M_FUN,int,int,int) //! @} FLEXT_D_ADDMETHOD #endif flext-0-6-3/source/fldefs_methbind.h000066400000000000000000000022551446466241400174450ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_methbind.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_METHBIND_H #define __FLEXT_DEFS_METHBIND_H /*! \defgroup FLEXT_D_BINDMETHOD Bind flext methods to symbols @{ */ /*! \brief Bind a handler for a method with an anything argument to a symbol */ #define FLEXT_BINDMETHOD(SYM,M_FUN,DATA) \ \ flext_base::BindMethod(SYM,FLEXT_CALL_PRE(M_FUN),DATA) /*! \brief Unbind any handler for a method from a symbol \note Memory associated to the DATA parameter of FLEXT_BINDMETHOD will *not* be freed here. */ #define FLEXT_UNBINDMETHOD(SYM) \ \ flext_base::UnbindMethod(SYM) /*! \brief Unbind any handler for a method from a symbol and return user data pointer by DATA \note Memory associated to the DATA parameter of FLEXT_BINDMETHOD will *not* be freed here. */ #define FLEXT_UNBINDMETHOD_X(SYM,DATA) \ \ flext_base::UnbindMethod(SYM,&DATA) //! @} FLEXT_D_BINDMETHOD #endif flext-0-6-3/source/fldefs_methcall.h000066400000000000000000000037631446466241400174510ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_methbind.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_METHCALL_H #define __FLEXT_DEFS_METHCALL_H /*! \defgroup FLEXT_D_CALLMETHOD Call flext methods manually \ingroup FLEXT_D_METHOD @{ */ //! Call a (already defined) method with no arguments #define FLEXT_CALLMETHOD(M_FUN) \ \ FLEXT_CALL_PRE(M_FUN)(this) //! Call a (already defined) method with variable list arguments #define FLEXT_CALLMETHOD_V(M_FUN,ARGC,ARGV) \ \ FLEXT_CALL_PRE(M_FUN)(this,ARGC,(t_atom *)(ARGV)) //! Call a (already defined) method with anything arguments #define FLEXT_CALLMETHOD_A(M_FUN,HDR,ARGC,ARGV) \ \ FLEXT_CALL_PRE(M_FUN)(this,(t_symbol *)(HDR),ARGC,(t_atom *)(ARGV)) //! Call a (already defined) method with a data package (void *) #define FLEXT_CALLMETHOD_X(M_FUN,DATA) \ \ FLEXT_CALL_PRE(M_FUN)(this,DATA) //! Call a (already defined) method with 1 enum type argument #define FLEXT_CALLMETHOD_E(M_FUN,ARG) \ \ FLEXT_CALL_PRE(M_FUN)(this,ARG) //! Call a (already defined) method with 1 argument #define FLEXT_CALLMETHOD_1(M_FUN,ARG) \ \ FLEXT_CALL_PRE(M_FUN)(this,ARG) //! Call a (already defined) method with 2 arguments #define FLEXT_CALLMETHOD_2(M_FUN,ARG1,ARG2) \ \ FLEXT_CALL_PRE(M_FUN)(this,ARG1,ARG2) //! Call a (already defined) method with 3 arguments #define FLEXT_CALLMETHOD_3(M_FUN,ARG1,ARG2,ARG3) \ \ FLEXT_CALL_PRE(M_FUN)(this,ARG1,ARG2,ARG3) //! Call a (already defined) method with 4 arguments #define FLEXT_CALLMETHOD_4(M_FUN,ARG1,ARG2,ARG3,ARG4) \ \ FLEXT_CALL_PRE(M_FUN)(this,ARG1,ARG2,ARG3,ARG4) //! Call a (already defined) method with 5 arguments #define FLEXT_CALLMETHOD_5(M_FUN,ARG1,ARG2,ARG3,ARG4,ARG5) \ \ FLEXT_CALL_PRE(M_FUN)(this,ARG1,ARG2,ARG3,ARG4,ARG5) //! @} FLEXT_D_CALLMETHOD #endif flext-0-6-3/source/fldefs_methcb.h000066400000000000000000000100741446466241400171130ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_methcb.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_METHCB_H #define __FLEXT_DEFS_METHCB_H /*! \defgroup FLEXT_D_CALLBACK Declare callbacks for class methods \ingroup FLEXT_D_METHOD @{ */ //! Set up a method callback with no arguments #define FLEXT_CALLBACK(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c) \ { FLEXT_CAST(c)->M_FUN(); return true; } //! Set up a method callback for an anything argument #define FLEXT_CALLBACK_A(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,t_symbol *s,int argc,t_atom *argv) \ { FLEXT_CAST(c)->M_FUN(s,argc,argv); return true; } //! Set up a method callback for a variable argument list #define FLEXT_CALLBACK_V(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,int argc,t_atom *argv) \ { FLEXT_CAST(c)->M_FUN(argc,argv); return true; } //! Set up a method callback for a data package (void *) argument #define FLEXT_CALLBACK_X(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,void *data) \ { FLEXT_CAST(c)->M_FUN(data); return true; } //! Set up a method callback for an anything argument and a data package (e.g. for symbol-bound methods). #define FLEXT_CALLBACK_AX(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,t_symbol *s,int argc,t_atom *argv,void *data) \ { FLEXT_CAST(c)->M_FUN(s,argc,argv,data); return true; } //! Set up a timer callback #define FLEXT_CALLBACK_T(M_FUN) \ \ FLEXT_CALLBACK_X(M_FUN) //! Set up a method callback for a boolean argument #define FLEXT_CALLBACK_B(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,int &arg1) \ { FLEXT_CAST(c)->M_FUN(arg1 != 0); return true; } //! Set up a method callback for 1 argument #define FLEXT_CALLBACK_1(M_FUN,TP1) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1) \ { FLEXT_CAST(c)->M_FUN(arg1); return true; } //! Set up a method callback for 2 arguments #define FLEXT_CALLBACK_2(M_FUN,TP1,TP2) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1,TP2 &arg2) \ { FLEXT_CAST(c)->M_FUN(arg1,arg2); return true; } //! Set up a method callback for 3 arguments #define FLEXT_CALLBACK_3(M_FUN,TP1,TP2,TP3) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3) \ { FLEXT_CAST(c)->M_FUN(arg1,arg2,arg3); return true; } //! Set up a method callback for 4 arguments #define FLEXT_CALLBACK_4(M_FUN,TP1,TP2,TP3,TP4) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3,TP4 &arg4) \ { FLEXT_CAST(c)->M_FUN(arg1,arg2,arg3,arg4); return true; } //! Set up a method callback for 5 arguments #define FLEXT_CALLBACK_5(M_FUN,TP1,TP2,TP3,TP4,TP5) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3,TP4 &arg4,TP5 &arg5) \ { FLEXT_CAST(c)->M_FUN(arg1,arg2,arg3,arg4,arg5); return true; } // Shortcuts //! Set up a method callback for 1 float argument #define FLEXT_CALLBACK_F(M_FUN) \ \ FLEXT_CALLBACK_1(M_FUN,float) //! Set up a method callback for 2 float arguments #define FLEXT_CALLBACK_FF(M_FUN) \ \ FLEXT_CALLBACK_2(M_FUN,float,float) //! Set up a method callback for 3 float arguments #define FLEXT_CALLBACK_FFF(M_FUN) \ \ FLEXT_CALLBACK_3(M_FUN,float,float,float) //! Set up a method callback for 1 integer argument #define FLEXT_CALLBACK_I(M_FUN) \ \ FLEXT_CALLBACK_1(M_FUN,int) //! Set up a method callback for 2 integer arguments #define FLEXT_CALLBACK_II(M_FUN) \ \ FLEXT_CALLBACK_2(M_FUN,int,int) //! Set up a method callback for 3 integer arguments #define FLEXT_CALLBACK_III(M_FUN) \ \ FLEXT_CALLBACK_3(M_FUN,int,int,int) //! Set up a method callback for 1 symbol argument #define FLEXT_CALLBACK_S(M_FUN) \ \ FLEXT_CALLBACK_1(M_FUN,t_symptr) //! \deprecated #define FLEXT_CALLBACK_G FLEXT_CALLBACK_V //! @} FLEXT_D_CALLBACK #endif flext-0-6-3/source/fldefs_meththr.h000066400000000000000000000171471446466241400173340ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_meththr.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_METHTHR_H #define __FLEXT_DEFS_METHTHR_H #ifdef FLEXT_THREADS /*! \defgroup FLEXT_D_THREAD Declare threaded method callbacks @{ */ //! Set up a threaded method callback with no arguments #define FLEXT_THREAD(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c) { \ thr_params *p = new thr_params; \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ delete p; \ if(ok) { \ th->M_FUN(); \ th->PopThread(); \ } \ } //! Set up a threaded method callback for an anything argument #define FLEXT_THREAD_A(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,t_symbol *s,int argc,t_atom *argv) { \ thr_params *p = new thr_params; p->set_any(s,argc,argv); \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ AtomAnything *args = p->var[0]._any; \ delete p; \ if(ok) { \ th->M_FUN(args->Header(),args->Count(),args->Atoms()); \ th->PopThread(); \ } \ delete args; \ } //! Set up a threaded method callback for a variable argument list #define FLEXT_THREAD_V(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,int argc,t_atom *argv) { \ thr_params *p = new thr_params; p->set_list(argc,argv); \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ AtomList *args = p->var[0]._list; \ delete p; \ if(ok) { \ th->M_FUN(args->Count(),args->Atoms()); \ th->PopThread(); \ } \ delete args; \ } /*! \brief Set up a threaded method callback for an arbitrary data struct. \note Data is pure... no destructor is called upon delete */ #define FLEXT_THREAD_X(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,void *data) { \ thr_params *p = new thr_params; p->var[0]._ext = data; \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ void *data = p->var[0]._ext; \ delete p; \ if(ok) { \ th->M_FUN(data); \ th->PopThread(); \ } \ /* delete (char *)data; */ \ } //! Set up a threaded method callback for a boolean argument #define FLEXT_THREAD_B(M_FUN) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,int &arg1) { \ thr_params *p = new thr_params; p->var[0]._bool = arg1 != 0; \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ bool b = p->var[0]._bool; \ delete p; \ if(ok) { \ th->M_FUN(b); \ th->PopThread(); \ } \ } //! Set up a threaded method callback for 1 argument #define FLEXT_THREAD_1(M_FUN,TP1) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1) { \ thr_params *p = new thr_params(1); \ p->var[0]._ ## TP1 = arg1; \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ const TP1 v1 = p->var[0]._ ## TP1; \ delete p; \ if(ok) { \ th->M_FUN(v1); \ th->PopThread(); \ } \ } //! Set up a threaded method callback for 2 arguments #define FLEXT_THREAD_2(M_FUN,TP1,TP2) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1,TP2 &arg2) { \ thr_params *p = new thr_params(2); \ p->var[0]._ ## TP1 = arg1; \ p->var[1]._ ## TP2 = arg2; \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ const TP1 v1 = p->var[0]._ ## TP1; \ const TP1 v2 = p->var[1]._ ## TP2; \ delete p; \ if(ok) { \ th->M_FUN(v1,v2); \ th->PopThread(); \ } \ } //! Set up a threaded method callback for 3 arguments #define FLEXT_THREAD_3(M_FUN,TP1,TP2,TP3) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3) { \ thr_params *p = new thr_params(3); \ p->var[0]._ ## TP1 = arg1; \ p->var[1]._ ## TP2 = arg2; \ p->var[2]._ ## TP3 = arg3; \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ const TP1 v1 = p->var[0]._ ## TP1; \ const TP2 v2 = p->var[1]._ ## TP2; \ const TP3 v3 = p->var[2]._ ## TP3; \ delete p; \ if(ok) { \ th->M_FUN(v1,v2,v3); \ th->PopThread(); \ } \ } //! Set up a threaded method callback for 4 arguments #define FLEXT_THREAD_4(M_FUN,TP1,TP2,TP3,TP4) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3,TP4 &arg4) { \ thr_params *p = new thr_params(4); \ p->var[0]._ ## TP1 = arg1; \ p->var[1]._ ## TP2 = arg2; \ p->var[2]._ ## TP3 = arg3; \ p->var[3]._ ## TP4 = arg4; \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ const TP1 v1 = p->var[0]._ ## TP1; \ const TP2 v2 = p->var[1]._ ## TP2; \ const TP3 v3 = p->var[2]._ ## TP3; \ const TP4 v4 = p->var[3]._ ## TP4; \ delete p; \ if(ok) { \ th->M_FUN(v1,v2,v3,v4); \ th->PopThread(); \ } \ } //! Set up a threaded method callback for 5 arguments #define FLEXT_THREAD_5(M_FUN,TP1,TP2,TP3,TP4,TP5) \ static bool FLEXT_CALL_PRE(M_FUN)(flext_base *c,TP1 &arg1,TP2 &arg2,TP3 &arg3,TP4 &arg4,TP5 &arg5) { \ thr_params *p = new thr_params(5); \ p->var[0]._ ## TP1 = arg1; \ p->var[1]._ ## TP2 = arg2; \ p->var[2]._ ## TP3 = arg3; \ p->var[3]._ ## TP4 = arg4; \ p->var[4]._ ## TP5 = arg5; \ return c->StartThread(FLEXT_THR_PRE(M_FUN),p,#M_FUN); \ } \ static void FLEXT_THR_PRE(M_FUN)(thr_params *p) { \ thisType *th = FLEXT_CAST(p->cl); \ bool ok = th->PushThread(); \ const TP1 v1 = p->var[0]._ ## TP1; \ const TP2 v2 = p->var[1]._ ## TP2; \ const TP3 v3 = p->var[2]._ ## TP3; \ const TP4 v4 = p->var[3]._ ## TP4; \ const TP5 v5 = p->var[4]._ ## TP5; \ delete p; \ if(ok) { \ th->M_FUN(v1,v2,v3,v4,v5); \ th->PopThread(); \ } \ } //! Shortcuts //! Set up a threaded method callback for 1 float argument #define FLEXT_THREAD_F(M_FUN) \ \ FLEXT_THREAD_1(M_FUN,float) //! Set up a threaded method callback for 2 float arguments #define FLEXT_THREAD_FF(M_FUN) \ \ FLEXT_THREAD_2(M_FUN,float,float) //! Set up a threaded method callback for 3 float arguments #define FLEXT_THREAD_FFF(M_FUN) \ \ FLEXT_THREAD_3(M_FUN,float,float,float) //! Set up a threaded method callback for 1 integer argument #define FLEXT_THREAD_I(M_FUN) \ \ FLEXT_THREAD_1(M_FUN,int) //! Set up a threaded method callback for 2 integer arguments #define FLEXT_THREAD_II(M_FUN) \ \ FLEXT_THREAD_2(M_FUN,int,int) //! Set up a threaded method callback for 3 integer arguments #define FLEXT_THREAD_III(M_FUN) \ \ FLEXT_THREAD_3(M_FUN,int,int,int) //! Set up a threaded method callback for 1 symbol argument #define FLEXT_THREAD_S(M_FUN) \ \ FLEXT_THREAD_1(M_FUN,t_symptr) // deprecated #define FLEXT_THREAD_G FLEXT_THREAD_V //! @} FLEXT_D_THREAD #endif // FLEXT_THREADS #endif flext-0-6-3/source/fldefs_setup.h000066400000000000000000000230111446466241400170040ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldefs_setup.h \brief This file contains all #defines for actual usage */ #ifndef __FLEXT_DEFS_SETUP_H #define __FLEXT_DEFS_SETUP_H // ==================================================================================== /*! \defgroup FLEXT_D_INSTANCE Class instantiation \note For stand-alone externals (not part of a library) the name of your class \note is of importance! It must be the same as the external (excluded an eventual ~ (tilde)) There are additional parameters that can be included in the NAME field of FLEXT_NEW etc.: - There may be additional names (aliases) appened, separated by spaces - There may be a help path prepended, separated by a colon - This help path doesn't work for Max/MSP. There you'll have to use a object mapping file (Max/MSP version >= 4.2) @{ */ /*! \defgroup FLEXT_D_NEW Stand-alone class instantiation Makes an actual instance of a stand-alone class. */ /*! \defgroup FLEXT_D_NEW_DSP Dsp class instantiation Makes an actual instance of a dsp (aka "tilde") class (with signal processing). */ /*! \defgroup FLEXT_D_LIB Library class instantiation Makes an actual instance of a class which is part of an object library (and not stand-alone). */ /*! \defgroup FLEXT_D_LIB_DSP Dsp library class instantiation Makes an actual instance of a dsp (aka "tilde") class with signal processing which is part of an object library (and not stand-alone). */ // NO ARGUMENTS // ---------------------------------------- /*! \brief Implementation of a flext class with no arguments \ingroup FLEXT_D_NEW \param NAME the object's actual name(s) as a string (like "*", "trigger", "noise~", etc.) \param NEW_CLASS the object's C++ class name */ #define FLEXT_NEW(NAME,NEW_CLASS) \ \ REAL_NEW(NAME,NEW_CLASS,0,0,0) /*! \brief Implementation of a flext dsp class with no arguments \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP(NAME,NEW_CLASS) \ \ REAL_NEW(NAME,NEW_CLASS,1,0,0) /*! \brief Implementation of a flext dsp class with no arguments and no dsp inlet \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP0(NAME,NEW_CLASS) \ \ REAL_NEW(NAME,NEW_CLASS,1,1,0) /*! \brief Implementation of a flext class (part of a library) with no arguments \ingroup FLEXT_D_LIB */ #define FLEXT_LIB(NAME,NEW_CLASS) \ \ REAL_NEW(NAME,NEW_CLASS,0,0,1) /*! \brief Implementation of a flext dsp class (part of a library) with no arguments \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP(NAME,NEW_CLASS) \ \ REAL_NEW(NAME,NEW_CLASS,1,0,1) /*! \brief Implementation of a flext dsp class (part of a library) with no arguments and no dsp inlet \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP0(NAME,NEW_CLASS) \ \ REAL_NEW(NAME,NEW_CLASS,1,1,1) // VARIABLE ARGUMENT LIST // ---------------------------------------- /*! \brief Implementation of a flext class with a variable argument list \ingroup FLEXT_D_NEW */ #define FLEXT_NEW_V(NAME,NEW_CLASS) \ \ REAL_NEW_V(NAME,NEW_CLASS,0,0,0) /*! \brief Implementation of a flext dsp class with a variable argument list \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP_V(NAME,NEW_CLASS) \ \ REAL_NEW_V(NAME,NEW_CLASS,1,0,0) /*! \brief Implementation of a flext dsp class with a variable argument list and no dsp inlet \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP0_V(NAME,NEW_CLASS) \ \ REAL_NEW_V(NAME,NEW_CLASS,1,1,0) /*! \brief Implementation of a flext class (part of a library) with a variable argument list \ingroup FLEXT_D_LIB */ #define FLEXT_LIB_V(NAME,NEW_CLASS) \ \ REAL_NEW_V(NAME,NEW_CLASS, 0,0,1) /*! \brief Implementation of a flext dsp class (part of a library) with a variable argument list \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP_V(NAME,NEW_CLASS) \ \ REAL_NEW_V(NAME,NEW_CLASS, 1,0,1) /*! \brief Implementation of a flext dsp class (part of a library) with a variable argument list and no dsp inlet \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP0_V(NAME,NEW_CLASS) \ \ REAL_NEW_V(NAME,NEW_CLASS, 1,1,1) // ONE ARGUMENT // ---------------------------------------- /*! \brief Implementation of a flext class with one argument \ingroup FLEXT_D_NEW */ #define FLEXT_NEW_1(NAME,NEW_CLASS, TYPE) \ \ REAL_NEW_1(NAME,NEW_CLASS, 0,0,0, TYPE) /*! \brief Implementation of a flext dsp class with one argument \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP_1(NAME,NEW_CLASS, TYPE) \ \ REAL_NEW_1(NAME,NEW_CLASS, 1,0,0, TYPE) /*! \brief Implementation of a flext dsp class with one argument and no dsp inlet \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP0_1(NAME,NEW_CLASS, TYPE) \ \ REAL_NEW_1(NAME,NEW_CLASS, 1,1,0, TYPE) /*! \brief Implementation of a flext class (part of a library) with one argument \ingroup FLEXT_D_LIB */ #define FLEXT_LIB_1(NAME,NEW_CLASS, TYPE) \ \ REAL_NEW_1(NAME,NEW_CLASS, 0,0,1, TYPE) /*! \brief Implementation of a flext dsp class (part of a library) with one argument \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP_1(NAME,NEW_CLASS, TYPE) \ \ REAL_NEW_1(NAME,NEW_CLASS, 1,0,1, TYPE) /*! \brief Implementation of a flext dsp class (part of a library) with one argument and no dsp inlet \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP0_1(NAME,NEW_CLASS, TYPE) \ \ REAL_NEW_1(NAME,NEW_CLASS, 1,1,1, TYPE) // TWO ARGUMENTS // ---------------------------------------- /*! \brief Implementation of a flext class with 2 arguments \ingroup FLEXT_D_NEW */ #define FLEXT_NEW_2(NAME,NEW_CLASS, TYPE1, TYPE2) \ \ REAL_NEW_2(NAME,NEW_CLASS, 0,0,0, TYPE1, TYPE2) /*! \brief Implementation of a flext dsp class with 2 arguments \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP_2(NAME,NEW_CLASS, TYPE1, TYPE2) \ \ REAL_NEW_2(NAME,NEW_CLASS, 1,0,0, TYPE1, TYPE2) /*! \brief Implementation of a flext dsp class with 2 arguments and no dsp inlet \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP0_2(NAME,NEW_CLASS, TYPE1, TYPE2) \ \ REAL_NEW_2(NAME,NEW_CLASS, 1,1,0, TYPE1, TYPE2) /*! \brief Implementation of a flext class (part of a library) with 2 arguments \ingroup FLEXT_D_LIB */ #define FLEXT_LIB_2(NAME,NEW_CLASS, TYPE1, TYPE2) \ \ REAL_NEW_2(NAME,NEW_CLASS, 0,0,1, TYPE1, TYPE2) /*! \brief Implementation of a flext dsp class (part of a library) with 2 arguments \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP_2(NAME,NEW_CLASS, TYPE1, TYPE2) \ \ REAL_NEW_2(NAME,NEW_CLASS, 1,0,1, TYPE1, TYPE2) /*! \brief Implementation of a flext dsp class (part of a library) with 2 arguments and no dsp inlet \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP0_2(NAME,NEW_CLASS, TYPE1, TYPE2) \ \ REAL_NEW_2(NAME,NEW_CLASS, 1,1,1, TYPE1, TYPE2) // THREE ARGUMENTS // ---------------------------------------- /*! \brief Implementation of a flext class with 3 arguments \ingroup FLEXT_D_NEW */ #define FLEXT_NEW_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) \ \ REAL_NEW_3(NAME,NEW_CLASS, 0,0,0, TYPE1, TYPE2, TYPE3) /*! \brief Implementation of a flext dsp class with 3 arguments \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) \ \ REAL_NEW_3(NAME,NEW_CLASS, 1,0,0, TYPE1, TYPE2, TYPE3) /*! \brief Implementation of a flext dsp class with 3 arguments and no dsp inlet \ingroup FLEXT_D_NEW_DSP */ #define FLEXT_NEW_DSP0_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) \ \ REAL_NEW_3(NAME,NEW_CLASS, 1,1,0, TYPE1, TYPE2, TYPE3) /*! \brief Implementation of a flext class (part of a library) with 3 arguments \ingroup FLEXT_D_LIB */ #define FLEXT_LIB_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) \ \ REAL_NEW_3(NAME,NEW_CLASS, 0,0,1, TYPE1, TYPE2, TYPE3) /*! \brief Implementation of a flext dsp class (part of a library) with 3 arguments \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) \ \ REAL_NEW_3(NAME,NEW_CLASS, 1,0,1, TYPE1, TYPE2, TYPE3) /*! \brief Implementation of a flext dsp class (part of a library) with 3 arguments and no dsp inlet \ingroup FLEXT_D_LIB_DSP */ #define FLEXT_LIB_DSP0_3(NAME,NEW_CLASS, TYPE1, TYPE2, TYPE3) \ \ REAL_NEW_3(NAME,NEW_CLASS, 1,1,1, TYPE1, TYPE2, TYPE3) // deprecated stuff /*! \defgroup FLEXT_D_DEPRECATED Deprecated definitions \deprecated @{ */ #define FLEXT_NEW_G FLEXT_NEW_V #define FLEXT_NEW_TILDE FLEXT_NEW_DSP #define FLEXT_NEW_TILDE_G FLEXT_NEW_DSP_V #define FLEXT_NEW_TILDE_1 FLEXT_NEW_DSP_1 #define FLEXT_NEW_TILDE_2 FLEXT_NEW_DSP_2 #define FLEXT_NEW_TILDE_3 FLEXT_NEW_DSP_3 #define FLEXT_LIB_G FLEXT_LIB_V #define FLEXT_LIB_TILDE FLEXT_LIB_DSP #define FLEXT_LIB_TILDE_G FLEXT_LIB_DSP_V #define FLEXT_LIB_TILDE_1 FLEXT_LIB_DSP_1 #define FLEXT_LIB_TILDE_2 FLEXT_LIB_DSP_2 #define FLEXT_LIB_TILDE_3 FLEXT_LIB_DSP_3 #define FLEXT_TILDE_SETUP FLEXT_DSP_SETUP //! @} FLEXT_D_DEPRECATED /*! \defgroup FLEXT_D_LIBRARY Definitions for library objects @{ */ /*! \brief Specify that to declare the library itself. \note If you have a library this is compulsory (to register all the objects of the library) */ #define FLEXT_LIB_SETUP(NAME,SETUPFUN) REAL_LIB_SETUP(NAME,SETUPFUN) /*! \brief Register an object in the library. \note This is used in the library setup function */ #define FLEXT_SETUP(cl) REAL_SETUP(cl,0) /*! \brief Register a DSP object in the library. \note This is used in the library setup function */ #define FLEXT_DSP_SETUP(cl) REAL_SETUP(cl,1) //! @} FLEXT_D_LIBRARY //! @} FLEXT_D_INSTANCE #endif flext-0-6-3/source/fldoxygen.h000066400000000000000000000167601446466241400163350ustar00rootroot00000000000000#ifndef __FLEXT_DOXYGEN_H #define __FLEXT_DOXYGEN_H /*! \file fldoxygen.h \brief Doxygen definitions \remark There is no code in here, just documentation stuff. */ /*! \mainpage flext - a C++ layer for cross-platform development of PD and Max/MSP objects \section INTRO Introduction Currently there exist two widely used modular systems for real-time audio that can be extended by self-written objects (so called "externals"):
Max (http://www.cycling74.com) and Pure Data (http://www.pure-data.org) . Both come with APIs that are not very different (as they share their origin), but as well not quite the same. Flext seeks to provide a unifying interface for the APIs of those real-time systems while also concentrating on making use of the advantages of the object orientation of the C++ language. Consequently, flext allows to write externals (or libraries of a number of these), that can be compiled for both systems (with various compilers on a few platforms) without changes to the source code. Flext also tries to overcome some limitations of the real-time systems and introduces new features. The advantages of flext are:
  • Identical source code for PD and Max/MSP objects on a number of platforms
  • Better readability of code compared to straight C externals
  • Faster development, more robust coding
  • Sharing of common methods and data by using base classes
  • Transparent use of threads for methods
  • Libraries of externals in Max/MSP
  • More than 3 typed creation arguments possible for Max/MSP
  • Any input to any object's inlet (with the exception of signal streams)
  • Control of the object state by use of Max/Jitter-like "attributes"
Naturally there are some cons, too:
  • Introduces a small overhead to speed of message handling
  • Overhead in object size (due to possibly unneeded library code) when statically linked
Currently, flext supports
  • PD on Windows with Microsoft Visual C++, Borland C++ and gcc(cygwin) compilers
  • PD on Linux with gcc
  • PD on Mac OSX with gcc (makefile or Xcode)
  • Max/MSP on Mac OS9 and OSX with Metrowerks CodeWarrior
\section LICENSE License Flext is covered by the GPL. flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (C) 2001-2005 Thomas Grill This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. In the official flext distribution, the GNU General Public License is in the file gpl.txt
Also see the file license.txt for notes on referenced works and their license texts. \section DOWNLOAD Download Download the latest flext version from http://grrrr.org/ext/flext .
Alternatively, you can check out the cvs version from http://sourceforge.net/projects/pure-data . \section USAGE Usage As a developer, you should know the C++ language, how to use a makefile (especially necessary for linux) and how to steer your compiler.
Flext can be compiled as a static library which has then to be linked to the code of your external. For most applications you won't have to use any of the native PD or Max/MSP API functions as they are all encapsulated by flext. So let's come to the point... how does a typical flext object look like? This is the object "attr1", one of the flext tutorial examples: \verbatim // enable attribute processing #define FLEXT_ATTRIBUTES 1 // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif \endverbatim With these lines, all the necessary definitions from the flext package have been included. \verbatim class attr1: public flext_base { FLEXT_HEADER(attr1,flext_base) \endverbatim A flext class is simply defined by inheriting from the flext_base (see also \ref FLEXT_CLASS) or flext_dsp (see also \ref FLEXT_DSP) classes. Additionally some information has to be added using FLEXT_HEADER (see \ref FLEXT_D_HEADER) \verbatim public: // constructor attr1(); \endverbatim Normally the constructor takes the creation arguments of an object. Here there are none. \verbatim protected: void m_trigger(float f); // stored argument float arg; \endverbatim These are methods and data elements for internal class usage. Flext doesn't know about them as long as they are not registered. \verbatim private: // callback for method "m_trigger" (with one float argument) FLEXT_CALLBACK_F(m_trigger); // define attribute callbacks for variable "arg" (with GET and SET properties) FLEXT_ATTRVAR_F(arg); }; \endverbatim For each method that shall be exposed to the realtime-system (for receiving messages) and every attribute (for setting and getting values) callbacks have to be set up. The functions in the groups \ref FLEXT_D_CALLBACK and \ref FLEXT_D_ATTRIB allow for their convenient definition. \verbatim // instantiate the class FLEXT_NEW("attr1",attr1) \endverbatim With FLEXT_NEW the class is registered for the real-time system. The number of creation arguments and their types must be taken into account here. There are several variants depending on whether a message oriented (see \ref FLEXT_D_NEW) or a DSP object (see \ref FLEXT_D_NEW_DSP) is created and whether it resides in a object library (see \ref FLEXT_D_LIB and \ref FLEXT_D_LIB_DSP).
\verbatim attr1::attr1(): arg(0) // initialize argument { // define inlets AddInAnything(); // first inlet of type anything (index 0) // define outlets AddOutFloat(); // one float outlet (has index 0) \endverbatim Every inlet and outlet that the object shall have has to be registered. This is done with the functions in \ref FLEXT_C_IO_ADD. \verbatim // register methods FLEXT_ADDMETHOD(0,m_trigger); // register method (for floats) "m_trigger" for inlet 0 FLEXT_ADDATTR_VAR1("arg",arg); // register attribute "arg" with variable arg } \endverbatim Likewise, every method (called by a message) (see \ref FLEXT_D_ADDMETHOD) and every attribute (see \ref FLEXT_D_ADDATTR) exposed to the system has to be registered. Here the registration at instance creation is shown - there's another way by registering at class setup level, which is more efficient but can only be used if the methods or attributes used are known beforehand (see \ref FLEXT_D_CADDMETHOD and \ref FLEXT_D_CADDATTR). \verbatim void attr1::m_trigger(float f) { float res = arg+f; // output value to outlet ToOutFloat(0,res); // (0 stands for the outlet index 0) } \endverbatim This is a method that is triggered with a message. It does some calculation and then outputs a value to an outlet. There are numerous functions (see \ref FLEXT_C_IO_OUT) supporting that functionality. Be sure to work through the examples provided with the flext tutorial. These should give you an overview about the possibilities of flext. The "modules" link at the top of the page leads to a complete reference of flext functions and classes. */ #endif flext-0-6-3/source/fldsp.cpp000066400000000000000000000105511446466241400157710ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2017 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldsp.cpp \brief Implementation of the flext dsp base class. */ #ifndef __FLEXT_DSP_CPP #define __FLEXT_DSP_CPP #include "flext.h" #include "flinternal.h" #include #include "flpushns.h" // === flext_dsp ============================================== FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::Setup(t_classid id) { #if FLEXT_SYS == FLEXT_SYS_PD // add_method1(c,cb_enable,"enable",A_FLOAT); AddMethod(id,0,MakeSymbol("enable"),&cb_enable); #endif } FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_dsp))::FLEXT_CLASSDEF(flext_dsp)() : srate(sys_getsr()),blksz(sys_getblksize()) #if MSP64 , inVec(NULL), outVec(NULL) #else , vecs(NULL) #endif #if FLEXT_SYS != FLEXT_SYS_MAX , dspon(true) #endif {} FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::Exit() { flext_base::Exit(); #if !MSP64 if(vecs) delete[] vecs; #endif } #if MSP64 FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::dspmeth64(flext_hdr *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam) { flext_dsp *obj = (flext_dsp *)userparam; obj->blksz = sampleframes; obj->inVec = ins; obj->outVec = outs; if(!obj->thisHdr()->z_disabled) { flext_base::indsp = true; obj->CbSignal(); flext_base::indsp = false; } } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::SetupDsp64(flext_hdr *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { // store current dsp parameters srate = samplerate; // overlap = sp[0]->s_sr/srate; // currently not used/exposed blksz = maxvectorsize; // will be overwritten in dspmeth64 anyway... // with the following call derived classes can do their eventual DSP setup if(CbDsp()) { // set the DSP function dsp_add64(dsp64, (t_object *)&x->obj, (t_dspmethod)dspmeth64, 0, this); } } #else FLEXT_TEMPIMPL(t_int *FLEXT_CLASSDEF(flext_dsp))::dspmeth(t_int *w) { flext_dsp *obj = (flext_dsp *)(size_t)w[1]; #if FLEXT_SYS == FLEXT_SYS_MAX if(!obj->thisHdr()->z_disabled) #else if(LIKELY(obj->dspon)) #endif { flext_base::indsp = true; obj->CbSignal(); flext_base::indsp = false; } return w+2; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::SetupDsp(t_signal **sp) { int i; int in = CntInSig(); int out = CntOutSig(); #if FLEXT_SYS == FLEXT_SYS_PD // min. 1 input channel! (CLASS_MAININLET in pd...) if(!in) in = 1; #endif // store current dsp parameters srate = sys_getsr(); // overlap = sp[0]->s_sr/srate; // currently not used/exposed blksz = sp[0]->s_n; // is this guaranteed to be the same as sys_getblksize() ? // store in and out signal vectors if((in+out) && !vecs) vecs = new t_signalvec[in+out]; for(i = 0; i < in; ++i) vecs[i] = sp[i]->s_vec; for(i = 0; i < out; ++i) vecs[in+i] = sp[in+i]->s_vec; // with the following call derived classes can do their eventual DSP setup if(CbDsp()) { // set the DSP function dsp_add((t_dspmethod)dspmeth, 1, this); } } #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::m_dsp(int /*n*/,t_signalvec const * /*insigs*/,t_signalvec const * /*outsigs*/) {} FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_dsp))::CbDsp() { // invoke legacy method m_dsp(Blocksize(),InSig(),OutSig()); return true; } // this function will be overridden anyway - the probably useless default is clearing all outputs FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::m_signal(int n,t_sample *const * /*insigs*/,t_sample *const *outs) { for(int i = 0; i < CntOutSig(); ++i) ZeroSamples(outs[i],n); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::CbSignal() { // invoke legacy method m_signal(Blocksize(),InSig(),OutSig()); } #if FLEXT_SYS == FLEXT_SYS_PD //void flext_dsp::cb_enable(flext_hdr *c,t_float on) { thisObject(c)->dspon = on != 0; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_dsp))::cb_enable(flext_base *b,float &on) { static_cast(b)->dspon = on != 0; return true; } #endif #include "flpopns.h" #endif // __FLEXT_DSP_CPP flext-0-6-3/source/fldsp.h000066400000000000000000000117761446466241400154500ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2017 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fldsp.h \brief Declares the flext dsp class */ #ifndef __FLDSP_H #define __FLDSP_H // include the header file declaring the base classes #include "flext.h" #include "flpushns.h" // === flext_dsp ================================================== FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_dsp); typedef FLEXT_SHARE FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_dsp)) flext_dsp; /*! \brief Flext dsp enabled base object */ FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_dsp): public flext_base { FLEXT_HEADER_S(FLEXT_CLASSDEF(flext_dsp),flext_base,Setup) friend class FLEXT_SHARE FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_base)); public: /*! \defgroup FLEXT_DSP Flext dsp class @{ */ /*! \defgroup FLEXT_C_DSP Basic dsp functionality @{ */ //! returns current sample rate float Samplerate() const { return srate; } //! returns current block (aka vector) size int Blocksize() const { return blksz; } //! returns array of input vectors (CntInSig() vectors) t_sample *const *InSig() const { #if MSP64 return inVec; #else return vecs; #endif } //! returns input vector t_sample *InSig(int i) const { return InSig()[i]; } //! returns array of output vectors (CntOutSig() vectors) // \todo cache that returned pointer t_sample *const *OutSig() const { int i = CntInSig(); #if MSP64 return outVec; #else // in PD we have at least one actual dsp in vector #if FLEXT_SYS == FLEXT_SYS_PD return vecs+(i?i:1); #elif FLEXT_SYS == FLEXT_SYS_MAX return vecs+i; #else #error #endif #endif } //! returns output vector t_sample *OutSig(int i) const { return OutSig()[i]; } //! typedef describing a signal vector typedef t_sample *t_signalvec; //! @} // --- inheritable virtual methods -------------------------------- /*! \defgroup FLEXT_C_DSP_VIRTUAL Flext virtual dsp functions @{ */ /*! \brief Called on every dsp init. \note Don't expect any valid data in the signal vectors! flext_dsp::CbDsp should not be called by the derived class \return true (default)... use DSP, false, don't use DSP */ virtual bool CbDsp(); /*! \brief Called with every signal vector - here you do the dsp calculation flext_dsp::CbSignal fills all output vectors with silence */ virtual void CbSignal(); /*! \brief Deprecated method for CbSignal \deprecated \param n: frames (aka samples) in one signal vector \param insigs: array of input vectors (get number with function CntInSig()) \param outsigs: array of output vectors (get number with function CntOutSig()) */ virtual void m_dsp(int n,t_signalvec const *insigs,t_signalvec const *outsigs); /*! \brief Deprecated method for CbSignal \deprecated \param n: frames (aka samples) in one signal vector \param insigs: array of input vectors (get number with function CntInSig()) \param outsigs: array of output vectors (get number with function CntOutSig()) */ virtual void m_signal(int n,t_sample *const *insigs,t_sample *const *outsigs); //! @} /*! \defgroup FLEXT_C_DSP_INOUT Flext dsp in-/outlet functions \note These must be called in the class' constructor @{ */ // --- inlet/outlet stuff ----------------------------------------- /*! \brief Add signal inlet(s) \param m Number of inlets to add */ void AddInSignal(int m = 1) { AddInlet(xlet_sig,m); } /*! \brief Add signal inlet (with description) \param desc Description of inlet */ void AddInSignal(const char *desc) { AddInlet(xlet_sig,1,desc); } /*! \brief Add signal outlet(s) \param m Number of inlets to add */ void AddOutSignal(int m = 1) { AddOutlet(xlet_sig,m); } /*! \brief Add signal outlet (with description) \param desc Description of outlet */ void AddOutSignal(const char *desc) { AddOutlet(xlet_sig,1,desc); } //! @} //! @} protected: FLEXT_CLASSDEF(flext_dsp)(); virtual void Exit(); private: // not static, could be different in different patchers.. float srate; int blksz; #if MSP64 t_signalvec *inVec; t_signalvec *outVec; #else t_signalvec *vecs; #endif // setup function static void Setup(t_classid c); #if FLEXT_SYS == FLEXT_SYS_PD static bool cb_enable(flext_base *c,float &on); bool dspon; #endif static inline flext_dsp *thisObject(flext_hdr *c) { return FLEXT_CAST(c->data); } // dsp stuff #if MSP64 void SetupDsp64(flext_hdr *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags); static void dspmeth64(flext_hdr *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam); #else // Max 32-bits or Pd void SetupDsp(t_signal **sp); static t_int *dspmeth(t_int *w); #endif }; #include "flpopns.h" #endif flext-0-6-3/source/flext.cpp000066400000000000000000000207311446466241400160040ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flext.cpp \brief Implementation of the flext base class. */ #ifndef __FLEXT_CPP #define __FLEXT_CPP #include "flext.h" #include "flinternal.h" #include "fldsp.h" #include #include "flpushns.h" // === flext_base ============================================ FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext_base))::curtag = NULL; FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::FLEXT_CLASSDEF(flext_base)() : incnt(0),outcnt(0) , insigs(0),outsigs(0) #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX ,outlets(NULL),inlets(NULL) #endif #if FLEXT_SYS == FLEXT_SYS_MAX ,indesc(NULL),outdesc(NULL) #endif { FLEXT_LOG1("%s - flext logging is on",thisName()); methhead = NULL; bindhead = NULL; if(HasAttributes()) { // initialize when attribute processing is enabled attrhead = new ItemCont; attrdata = new AttrDataCont; } else { attrhead = NULL; attrdata = NULL; } } /*! This virtual function is called after the object has been created, that is, after the constructor has been processed. It creates the inlets and outlets and the message and attribute lists. \note You can override it in your own class, but be sure to call it, \note otherwise no inlets/outlets will be created \note All inlet, outlets, method and attribute declarations must be made before a call to Init! \remark Creation of inlets/outlets can't be done upon declaration, as Max/MSP needs creation \remark in reverse. */ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::Init() { bool ok = flext_obj::Init(); if(ok) ok = InitInlets() && InitOutlets(); if(ok) { #if FLEXT_SYS == FLEXT_SYS_MAX // according to the Max/MSP SDK this should be prior to any inlet creation, BUT // that doesn't seem to be true... multiple signal ins and additional inlets don't seem to work then if(NeedDSP()) dsp_setup(thisHdr(),CntInSig()); // signal inlets #endif if(HasAttributes() && m_holdaargc && m_holdaargv) { // initialize creation attributes ok = InitAttrib(m_holdaargc,m_holdaargv); } } return ok; } /*! This virtual function is called before the destructor. We do this because here we can still call virtual methods. */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::Exit() { #if FLEXT_SYS == FLEXT_SYS_MAX // according to David Z. one should do that first... if(NeedDSP()) dsp_free(thisHdr()); #endif #if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_NOATTREDIT) // attribute editor window may still be open -> close it gfxstub_deleteforkey(thisHdr()); #endif #ifdef FLEXT_THREADS StopThreads(); #endif // send remaining pending messages for this object QFlush(this); // delete message lists if(bindhead) delete bindhead; // ATTENTION: the object must free all memory associated to bindings itself if(methhead) delete methhead; if(attrhead) delete attrhead; if(attrdata) delete attrdata; #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX if(outlets) delete[] outlets; if(inlets) { FLEXT_ASSERT(incnt > 1); for(int ix = 1; ix < incnt; ++ix) if(inlets[ix-1]) { // release proxy object #if FLEXT_SYS == FLEXT_SYS_PD pd_free(&inlets[ix-1]->obj.ob_pd); #elif FLEXT_SYS == FLEXT_SYS_MAX freeobject((object *)inlets[ix-1]); #endif } delete[] inlets; } #endif #if FLEXT_SYS == FLEXT_SYS_MAX if(indesc) { for(int i = 0; i < incnt; ++i) if(indesc[i]) delete[] indesc[i]; delete[] indesc; } if(outdesc) { for(int i = 0; i < outcnt; ++i) if(outdesc[i]) delete[] outdesc[i]; delete[] outdesc; } #endif flext_obj::Exit(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddMessageMethods(t_class *c,bool dsp,bool dspin) { add_loadbang(c,cb_loadbang); #if FLEXT_SYS == FLEXT_SYS_PD class_addmethod(c,(t_method)cb_click,gensym(const_cast("click")),A_FLOAT,A_FLOAT,A_FLOAT,A_FLOAT,A_FLOAT,A_NULL); #elif FLEXT_SYS == FLEXT_SYS_MAX add_assist(c,cb_assist); add_dblclick(c,cb_click); #endif SetProxies(c,dsp); StartQueue(); if(dsp) { #if FLEXT_SYS == FLEXT_SYS_MAX #if MSP64 add_dsp64(c,cb_dsp64); #else add_dsp(c,cb_dsp); #endif dsp_initclass(); #elif FLEXT_SYS == FLEXT_SYS_PD if(dspin) CLASS_MAINSIGNALIN(c,flext_hdr,defsig); // float messages going into the left inlet are converted to signal add_dsp(c,cb_dsp); #else #error Platform not supported! #endif } } /*! Set up proxy classes and basic methods at class creation time This ensures that they are processed before the registered flext messages */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::Setup(t_classid id) { t_class *c = getClass(id); #if FLEXT_SYS == FLEXT_SYS_MAX if(!IsLib(id)) #endif AddMessageMethods(c,IsDSP(id),HasDSPIn(id)); if(HasAttributes(id)) { AddMethod(id,0,"getattributes",cb_ListAttrib); AddMethod(id,0,"getmethods",cb_ListMethods); #if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_NOATTREDIT) AddMethod(id,0,"attributedialog",cb_AttrDialog); #endif } #if FLEXT_SYS == FLEXT_SYS_PD SetGfx(id); #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_loadbang(flext_hdr *c) { Locker lock(c); thisObject(c)->CbLoadbang(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::m_loadbang() {} FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::CbLoadbang() { m_loadbang(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::CbClick() {} #if FLEXT_SYS == FLEXT_SYS_PD FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_click(flext_hdr *c,t_floatarg xpos,t_floatarg ypos,t_floatarg shift,t_floatarg ctrl,t_floatarg alt) { FLEXT_UNUSED(xpos); // keep compiler quiet FLEXT_UNUSED(ypos); // keep compiler quiet FLEXT_UNUSED(ctrl); // keep compiler quiet FLEXT_UNUSED(alt); // keep compiler quiet if(shift) { Locker lock(c); thisObject(c)->CbClick(); } } #endif #if FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_click(flext_hdr *c, Point pt, short mods) { Locker lock(c); thisObject(c)->CbClick(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_assist(flext_hdr *c,void * /*b*/,long msg,long arg,char *s) { Locker lock(c); flext_base *th = thisObject(c); switch(msg) { case 1: //ASSIST_INLET: if(arg < th->incnt && th->indesc[arg]) strcpy(s,th->indesc[arg]); break; case 2: //ASSIST_OUTLET: if(arg < th->outcnt) { if(th->outdesc[arg]) strcpy(s,th->outdesc[arg]); } else if(arg == th->outcnt && th->HasAttributes()) strcpy(s,"Attributes"); break; } } #endif #if MSP64 FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_dsp64(flext_hdr *c, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { Locker lock(c); flext_base *bobj = thisObject(c); #if FLEXT_SYS == FLEXT_SYS_MAX // we must extra-check here if it is really a DSP object // obviously, for objects that are part of a library, one dsp_initclass enables DSP for all if(!bobj->IsDSP()) return; #endif flext_dsp *obj; #ifdef FLEXT_DEBUG obj = dynamic_cast(bobj); #else obj = static_cast(bobj); #endif FLEXT_ASSERT(obj); obj->SetupDsp64(c,dsp64,count,samplerate,maxvectorsize,flags); } #else #if FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_dsp(flext_hdr *c,t_signal **sp,short *count) #else FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_dsp(flext_hdr *c,t_signal **sp) #endif { Locker lock(c); flext_base *bobj = thisObject(c); #if FLEXT_SYS == FLEXT_SYS_MAX // we must extra-check here if it is really a DSP object // obviously, for objects that are part of a library, one dsp_initclass enables DSP for all if(!bobj->IsDSP()) return; #endif flext_dsp *obj; #ifdef FLEXT_DEBUG obj = dynamic_cast(bobj); #else obj = static_cast(bobj); #endif FLEXT_ASSERT(obj); obj->SetupDsp(sp); } #endif FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::CbIdle() { return 0; } #include "flpopns.h" #endif // __FLEXT_CPP flext-0-6-3/source/flext.h000066400000000000000000000042201446466241400154440ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2023 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flext.h \brief This is the main flext include file. The basic definitions are set here and the necessary header files are included */ #ifndef __FLEXT_H #define __FLEXT_H /*! \defgroup FLEXT_GLOBAL Flext global definitions @{ */ //! \brief flext version number #define FLEXT_VERSION 603 //! \brief flext version string #define FLEXT_VERSTR "0.6.3" //! @} // determine System/OS/CPU #include "flprefix.h" // include headers necessary for multi-threading #ifdef FLEXT_THREADS #if FLEXT_THREADS == FLEXT_THR_POSIX extern "C" { #include #include } #elif FLEXT_THREADS == FLEXT_THR_MP #include #elif FLEXT_THREADS == FLEXT_THR_WIN32 #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x500 #include #include #else #error "Win32 threading model only supported for Win2000/XP or newer" #endif #else #error "Thread model not supported" #endif #endif // include all the flext interface definitions #include "fldefs.h" // include the basic flext object classes #include "flclass.h" // include the flext dsp class #include "fldsp.h" #ifdef FLEXT_INLINE // include all source code files # include "flatom.cpp" # include "flatom_part.cpp" # include "flatom_pr.cpp" # include "flattr.cpp" # include "flattr_ed.cpp" # include "flbase.cpp" # include "flbind.cpp" # include "flbuf.cpp" # include "fldsp.cpp" # include "flext.cpp" # include "flitem.cpp" # include "fllib.cpp" # include "flmap.cpp" # include "flmeth.cpp" # include "flmsg.cpp" # include "flout.cpp" # include "flproxy.cpp" # include "flqueue.cpp" # include "flsimd.cpp" # include "flsupport.cpp" # include "flthr.cpp" # include "fltimer.cpp" # include "flutil.cpp" # include "flxlet.cpp" #endif #endif // FLEXT_H flext-0-6-3/source/flfeatures.h000066400000000000000000000015231446466241400164650ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flfeatures.h \brief Detect version-specific features. */ #ifndef __FLFEATURES_H #define __FLFEATURES_H // check if PD API supports buffer dirty time #if defined(PD_DEVEL_VERSION) && defined(PD_MAJOR_VERSION) && defined(PD_MINOR_VERSION) #if PD_MINOR_VERSION >= 36 && PD_MINOR_VERSION <= 38 // array locks have been removed in devel_0_39 #define _FLEXT_HAVE_PD_GARRAYLOCKS #endif #if PD_MINOR_VERSION >= 36 #define _FLEXT_HAVE_PD_GARRAYUPDATETIME #endif #endif #if defined(MAC_VERSION) || defined(WIN_VERSION) // not for OS9 #define _FLEXT_HAVE_MAX_INUSEFLAG #endif #endif flext-0-6-3/source/flinternal.h000066400000000000000000000122541446466241400164660ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flinternal.h \brief Definitions for internal flext usage \internal Here, a few shortcuts for common Max/MSP or PD library calls and type definitions are declared */ #ifndef __FLEXT_INTERNALS_H #define __FLEXT_INTERNALS_H #include "flstdc.h" #if FLEXT_SYS == FLEXT_SYS_PD #define object_new(clss) pd_new(clss) #define object_free(obj) pd_free(&(obj)->ob_pd) #define add_dsp(clss,meth) class_addmethod(clss, (t_method)meth,gensym(const_cast("dsp")),A_NULL) #define add_bang(clss,meth) class_addbang(clss, (t_method)meth) #define add_float(clss,meth) class_addfloat(clss, (t_method)meth) #define add_floatn(clss,meth,n) class_addmethod(clss, (t_method)meth,gensym(const_cast("ft" #n)),A_FLOAT,A_NULL) #define add_flint(clss,meth) class_addfloat(clss, (t_method)meth) #define add_flintn(clss,meth,n) class_addmethod(clss, (t_method)meth,gensym(const_cast("ft" #n)),A_FLOAT,A_NULL) #define add_method(clss,meth,text) class_addmethod(clss, (t_method)meth, gensym(const_cast(text)), A_NULL) #define add_methodG(clss,meth,text) class_addmethod(clss, (t_method)meth, gensym(const_cast(text)), A_GIMME,A_NULL) #define add_method1(clss,meth,text,a1) class_addmethod(clss, (t_method)meth, gensym(const_cast(text)), a1,A_NULL) #define add_method2(clss,meth,text,a1,a2) class_addmethod(clss, (t_method)meth, gensym(const_cast(text)), a1,a2,A_NULL) #define add_method3(clss,meth,text,a1,a2,a3) class_addmethod(clss, (t_method)meth, gensym(const_cast(text)), a1,a2,a3,A_NULL) #define add_method4(clss,meth,text,a1,a2,a3,a4) class_addmethod(clss, (t_method)meth, gensym(const_cast(text)), a1,a2,a3,a4,A_NULL) #define add_method5(clss,meth,text,a1,a2,a3,a5) class_addmethod(clss, (t_method)meth, gensym(const_cast(text)), a1,a2,a3,a4,a5,A_NULL) #define add_loadbang(clss,meth) class_addmethod(clss,(t_method)meth, gensym(const_cast("loadbang")), A_NULL) #define add_anything(clss,meth) class_addanything(clss,meth) #define newout_signal(clss) outlet_new(clss,const_cast(flext::sym_signal)) #define newout_float(clss) outlet_new(clss,const_cast(flext::sym_float)) #define newout_flint(clss) outlet_new(clss,const_cast(flext::sym_float)) #define newout_list(clss) outlet_new(clss,const_cast(flext::sym_list)) #define newout_symbol(clss) outlet_new(clss,const_cast(flext::sym_symbol)) #define newout_anything(clss) outlet_new(clss,const_cast(flext::sym_anything)) #define outlet_flint(o,v) outlet_float(o,(float)(v)) typedef t_perfroutine t_dspmethod; #define qelem_new clock_new #define qelem_free clock_free #define qelem_set clock_delay #define qelem_front clock_delay #define qelem_unset clock_unset #define CRITON() #define CRITOFF() #elif FLEXT_SYS == FLEXT_SYS_MAX //#define object_new(clss) newobject(clss) #define object_free(obj) freeobject((object *)(obj)) #define add_dsp64(clss,meth) addmess((method)meth,const_cast("dsp64"),A_CANT,A_NOTHING) #define add_dsp(clss,meth) addmess((method)meth,const_cast("dsp"),A_CANT,A_NOTHING) #define add_bang(clss,meth) addbang((method)meth) #define add_float(clss,meth) addfloat((method)meth) #define add_floatn(clss,meth,n) addftx((method)meth,n) #define add_flint(clss,meth) addint((method)meth) #define add_flintn(clss,meth,n) addinx((method)meth,n) #define add_method(clss,meth,text) addmess((method)meth, text, A_NOTHING) #define add_methodG(clss,meth,text) addmess((method)meth, text, A_GIMME,A_NOTHING) #define add_method1(clss,meth,text,a1) addmess((method)meth, text, a1,A_NOTHING) #define add_method2(clss,meth,text,a1,a2) addmess((method)meth, text, a1,a2,A_NOTHING) #define add_method3(clss,meth,text,a1,a2,a3) addmess((method)meth, text, a1,a2,a3,A_NOTHING) #define add_method4(clss,meth,text,a1,a2,a3,a4) addmess((method)meth, text, a1,a2,a3,a4,A_NOTHING) #define add_method5(clss,meth,text,a1,a2,a3,a5) addmess((method)meth, text, a1,a2,a3,a4,a5,A_NOTHING) #define add_anything(clss,meth) addmess((method)meth, const_cast("anything"), A_GIMME,A_NOTHING) #define add_assist(clss,meth) addmess((method)meth, const_cast("assist"), A_CANT, A_NULL) #define add_loadbang(clss,meth) addmess((method)meth, const_cast("loadbang"), A_CANT, A_NULL) #define add_dblclick(clss,meth) addmess((method)meth, const_cast("dblclick"), A_CANT, A_NULL) #define newout_signal(clss) outlet_new(clss,"signal") #define newout_float(clss) outlet_new(clss,"float") #define newout_flint(clss) outlet_new(clss,"int") #define newout_list(clss) outlet_new(clss,"list") #define newout_symbol(clss) outlet_new(clss,"symbol") #define newout_anything(clss) outlet_new(clss,0) #define outlet_flint(o,v) outlet_int(o,(int)(v)) #define outlet_symbol(o,s) outlet_anything(o,s,0,NULL) #if MSP64 typedef t_perfroutine64 t_dspmethod; #else typedef t_perfroutine t_dspmethod; #endif #define CRITON() short state = lockout_set(1) #define CRITOFF() lockout_set(state) #endif #endif flext-0-6-3/source/flitem.cpp000066400000000000000000000071711446466241400161450ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flitem.cpp \brief Processing of method and attribute lists. */ #ifndef __FLEXT_ITEM_CPP #define __FLEXT_ITEM_CPP #include "flext.h" #include #include "flpushns.h" FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::ItemSet::~ItemSet() { clear(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ItemSet::clear() { for(FLEXT_TEMP_TYPENAME TablePtrMapDef::iterator it(*this); it; ++it) delete it.data(); TablePtrMap::clear(); } FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::Item::~Item() { if(nxt) delete nxt; } FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::ItemCont::ItemCont(): members(0),memsize(0),size(0),cont(NULL) {} FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::ItemCont::~ItemCont() { if(cont) { for(int i = 0; i < size; ++i) delete cont[i]; delete[] cont; } } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ItemCont::Resize(int nsz) { if(nsz > memsize) { int nmemsz = nsz+10; // increment maximum allocation size ItemSet **ncont = new ItemSet *[nmemsz]; // make new array if(cont) { memcpy(ncont,cont,size*sizeof(*cont)); // copy existing entries delete[] cont; } cont = ncont; // set current array memsize = nmemsz; // set new allocation size } // make new items while(size < nsz) cont[size++] = new ItemSet; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ItemCont::Add(Item *item,const t_symbol *tag,int inlet) { FLEXT_ASSERT(tag); if(!Contained(inlet)) Resize(inlet+2); ItemSet &set = GetInlet(inlet); Item *lst = set.find(tag); if(!lst) { Item *old = set.insert(tag,lst = item); FLEXT_ASSERT(!old); } else for(;;) if(!lst->nxt) { lst->nxt = item; break; } else lst = lst->nxt; members++; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::ItemCont::Remove(Item *item,const t_symbol *tag,int inlet,bool free) { FLEXT_ASSERT(tag); if(Contained(inlet)) { ItemSet &set = GetInlet(inlet); Item *lit = set.find(tag); for(Item *prv = NULL; lit; prv = lit,lit = lit->nxt) { if(lit == item) { if(prv) prv->nxt = lit->nxt; else if(lit->nxt) { Item *old = set.insert(tag,lit->nxt); FLEXT_ASSERT(!old); } else { Item *l = set.remove(tag); FLEXT_ASSERT(l == lit); } lit->nxt = NULL; if(free) delete lit; return true; } } } return false; } FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext_base))::Item *FLEXT_CLASSDEF(flext_base))::ItemCont::FindList(const t_symbol *tag,int inlet) { FLEXT_ASSERT(tag); return Contained(inlet)?GetInlet(inlet).find(tag):NULL; } // --- class item lists (methods and attributes) ---------------- /* typedef TablePtrMap ClassMap; static ClassMap classarr[2]; FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext_base))::ItemCont *FLEXT_CLASSDEF(flext_base))::GetClassArr(t_classid c,int ix) { ClassMap &map = classarr[ix]; ItemCont *cont = map.find(c); if(!cont) map.insert(c,cont = new ItemCont); return cont; } */ #include "flpopns.h" #endif // __FLEXT_ITEM_CPP flext-0-6-3/source/fllib.cpp000066400000000000000000000457211446466241400157600ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fllib.cpp \brief Code for handling of object (and library) creation functions. */ #ifndef __FLEXT_LIB_CPP #define __FLEXT_LIB_CPP #include "flext.h" #include "flinternal.h" #include #include #include #include #include "flpushns.h" #define ALIASDEL ',' #define ALIASSLASHES ":/\\" #if FLEXT_OS == FLEXT_OS_MAC #define ALIASSLASH ':' #elif FLEXT_OS == FLEXT_OS_WIN #if FLEXT_SYS == FLEXT_SYS_PD #define ALIASSLASH '/' #elif FLEXT_SYS == FLEXT_SYS_MAX #define ALIASSLASH '/' #else #error "Undefined" #endif #else // default to "/" #define ALIASSLASH '/' #endif //! Extract space-delimited words from a string FLEXT_TEMPLATE const char *extract(const char *name,int ix = 0) { static char tmp[1024]; const char *n = name; const char *del = strchr(name,ALIASDEL); if(del) { #if 0 char *t = tmp; while(n < del && (isspace(*n) || strchr(ALIASSLASHES,*n))) ++n; while(n < del && !isspace(*n)) { char c = *(n++); *(t++) = strchr(ALIASSLASHES,c)?ALIASSLASH:c; } while(*t == ALIASSLASH && t > tmp) --t; *t = 0; #endif if(ix < 0) { // eat white space in front of help definition ++del; while(*del && isspace(*del)) ++del; return del; } strncpy(tmp,name,del-name); tmp[del-name] = 0; n = tmp; } else if(ix < 0) return NULL; // no explicit help name while(*n && isspace(*n)) ++n; for(int i = 0; n && *n; ++i) { if(i == ix) { char *t = tmp; for(; *n && !isspace(*n); ++t,++n) *t = *n; *t = 0; return *tmp?tmp:NULL; } else { while(*n && !isspace(*n)) ++n; while(*n && isspace(*n)) ++n; } } return NULL; } //! Check if object's name ends with a tilde FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::chktilde(const char *objname) { // int stplen = strlen(setupfun); bool tilde = true; //!strncmp(setupfun,"_tilde",6); if((objname[strlen(objname)-1] == '~'?1:0)^(tilde?1:0)) { if(tilde) error("flext: %s (no trailing ~) is defined as a tilde object",objname); else error("flext::check_tilde: %s is no tilde object",objname); return true; } else return false; } // this class stands for one library of objects // there can be more if flext is a shared library class flext_library { public: flext_library(const t_symbol *nm) : name(nm) #if FLEXT_SYS == FLEXT_SYS_MAX , clss(NULL),dsp(false) #endif {} const t_symbol *name; #if FLEXT_SYS == FLEXT_SYS_MAX t_class *clss; bool dsp; #endif }; // this class stands for one registered object // it holds the class, type flags, constructor and destructor of the object and the creation arg types // it will never be destroyed FLEXT_TEMPLATE class flext_class: public flext_root { public: flext_class(t_class *&cl,flext_obj *(*newf)(int,t_atom *),void (*freef)(flext_hdr *)); t_class *const &clss; flext_obj *(*newfun)(int,t_atom *); void (*freefun)(flext_hdr *c); int argc; int *argv; flext_library *lib; bool dsp:1,noi:1,attr:1,dist:1; flext_base::ItemCont meths,attrs; }; FLEXT_TEMPIMPL(flext_class)::flext_class(t_class *&cl,flext_obj *(*newf)(int,t_atom *),void (*freef)(flext_hdr *)): clss(cl), newfun(newf),freefun(freef), argc(0),argv(NULL) , dist(false) {} FLEXT_TEMPIMPL(LibMap *FLEXT_CLASSDEF(flext_obj))::libnames = NULL; //! Store or retrieve registered classes FLEXT_TEMPIMPL(FLEXT_TEMPINST(flext_class) *FLEXT_CLASSDEF(flext_obj))::FindName(const t_symbol *s,FLEXT_TEMPINST(flext_class) *o) { if(!libnames) libnames = new LibMap; LibMap::iterator it = libnames->find(s); if(it != libnames->end()) return it->second; else if(o) { (*libnames)[s] = o; return o; } else return NULL; } FLEXT_TEMPIMPL(t_class *FLEXT_CLASSDEF(flext_obj))::getClass(t_classid cl) { return cl->clss; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::HasAttributes(t_classid cl) { return cl->attr; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::IsDSP(t_classid cl) { return cl->dsp; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::HasDSPIn(t_classid cl) { return !cl->noi; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::IsLib(t_classid cl) { return cl->lib != NULL; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::HasAttributes() const { return clss->attr; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::IsDSP() const { return clss->dsp; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::HasDSPIn() const { return !clss->noi; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::IsLib() const { return clss->lib != NULL; } #if FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_obj))::NeedDSP() const { return clss->dsp || (clss->lib && clss->lib->dsp); } #endif FLEXT_TEMPIMPL(flext_library *FLEXT_CLASSDEF(flext_obj))::curlib = NULL; FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::lib_init(const char *name,void setupfun()) { // make new library instance curlib = new flext_library(MakeSymbol(name)); flext::Setup(); // first register all classes try { setupfun(); } catch(std::exception &x) { error("%s - %s",name,x.what()); return; } catch(char *txt) { error("%s - %s",name,txt); return; } catch(...) { error("%s - Unknown exception at library setup",name); return; } #if FLEXT_SYS == FLEXT_SYS_MAX // then see if we got DSP classes // for Max/MSP, the library is represented by a special object (class) registered at startup // all objects in the library are clones of that library object - they share the same class ::setup( (t_messlist **)&curlib->clss, (t_newmethod)obj_new,(t_method)obj_free, sizeof(flext_hdr),NULL,A_GIMME,A_NULL); // for all classes in library add methods flext_base::AddMessageMethods(curlib->clss,curlib->dsp,true); #endif curlib = NULL; } #if FLEXT_SYS == FLEXT_SYS_PD FLEXT_TEMPIMPL(t_class *FLEXT_CLASSDEF(flext_obj))::buf_class = NULL; #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::obj_add(bool lib,bool dsp,bool noi,bool attr,const char *idname,const char *names,void setupfun(t_classid),FLEXT_CLASSDEF(flext_obj) *(*newfun)(int,t_atom *),void (*freefun)(flext_hdr *),int argtp1,...) { Locker lock; #if FLEXT_SYS == FLEXT_SYS_PD // register buffer helper class (if not present already) if(UNLIKELY(!buf_class)) { buf_class = class_new(gensym(const_cast(" flext buffer helper ")),NULL,NULL,sizeof(t_object),CLASS_PD|CLASS_NOINLET,A_NULL); if(buf_class) { // this can happen with double precision pure data add_dsp(buf_class,cb_buffer_dsp); // make an instance ::pd_new(buf_class); } else { // NULL case not handled (dsp precision mismatch 32<>64 bits) } } #endif // get first possible object name const t_symbol *nsym = MakeSymbol(FLEXT_TEMPINST(extract)(names)); #ifdef FLEXT_DEBUG if(dsp) chktilde(GetString(nsym)); #endif if(lib) { FLEXT_ASSERT(curlib); #if FLEXT_SYS == FLEXT_SYS_MAX curlib->dsp |= dsp; #endif } else { FLEXT_ASSERT(!curlib); // process_attributes = attr; } // set dynamic class pointer t_class **cl = #if FLEXT_SYS == FLEXT_SYS_MAX lib?&curlib->clss: #endif new t_class *; #if FLEXT_SYS == FLEXT_SYS_PD // register object class *cl = class_new( (t_symbol *)nsym, (t_newmethod)obj_new,(t_method)obj_free, sizeof(flext_hdr),CLASS_DEFAULT,A_GIMME,A_NULL); #elif FLEXT_SYS == FLEXT_SYS_MAX if(!lib) { ::setup( (t_messlist **)cl, (t_newmethod)obj_new,(t_method)obj_free, sizeof(flext_hdr),NULL,A_GIMME,A_NULL); // attention: in Max/MSP the *cl variable is not initialized after that call. // just the address is stored, the initialization then occurs with the first object instance! } #else #error Platform not implemented #endif // make new dynamic object FLEXT_TEMPINST(flext_class) *lo = new FLEXT_TEMPINST(flext_class)(*cl,newfun,freefun); lo->lib = curlib; lo->dsp = dsp; lo->noi = noi; lo->attr = attr; // post("ADDCLASS %s,%s = %p -> LIBOBJ %p -> %p (lib=%i,dsp=%i)",idname,names,*cl,lo,lo->clss,lib?1:0,dsp?1:0); // parse the argument type list and store it with the object if(argtp1 == FLEXTTPN_VAR) lo->argc = -1; else { int argtp,i; va_list marker; // parse a first time and count only va_start(marker,argtp1); for(argtp = argtp1; argtp != FLEXTTPN_NULL; ++lo->argc) argtp = (int)va_arg(marker,int); va_end(marker); lo->argv = new int[lo->argc]; // now parse and store va_start(marker,argtp1); for(argtp = argtp1,i = 0; i < lo->argc; ++i) { lo->argv[i] = argtp; argtp = (int)va_arg(marker,int); } va_end(marker); } // get unique class id t_classid clid = lo; // make help reference const char *helptxt = FLEXT_TEMPINST(extract)(names,-1); if(helptxt) { const char *sl = strchr(helptxt,'/'); if(sl && !sl[1]) // helptxt is only the path (path with trailing /) flext_obj::DefineHelp(clid,idname,helptxt,dsp); else // helptxt is path and patch name flext_obj::DefineHelp(clid,helptxt,NULL,dsp); } for(int ix = 0; ; ++ix) { // in this loop register all the possible aliases of the object const char *c = ix?FLEXT_TEMPINST(extract)(names,ix):GetString(nsym); if(!c || !*c) break; // add to name list const t_symbol *lsym = MakeSymbol(c); FindName(lsym,lo); #if FLEXT_SYS == FLEXT_SYS_PD if(ix > 0) // in PD the first name is already registered with class creation ::class_addcreator((t_newmethod)obj_new,(t_symbol *)lsym,A_GIMME,A_NULL); #elif FLEXT_SYS == FLEXT_SYS_MAX if(ix > 0 || lib) // in Max/MSP the first alias gets its name from the name of the object file, // unless it is a library (then the name can be different) ::alias(const_cast(c)); #else #error #endif } try { // call class setup function setupfun(clid); } catch(std::exception &x) { error("%s: %s",idname,x.what()); } catch(char *txt) { error("%s: %s",idname,txt); } catch(...) { error("%s - Unknown exception while initializing class",idname); } } #define NEWARGS 256 // must be larger than FLEXT_NEWARGS = 5 typedef FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_obj)) *(*libfun)(int,t_atom *); #if FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(flext_hdr *FLEXT_CLASSDEF(flext_obj))::obj_new(const t_symbol *s,short _argc_,t_atom *argv) #else FLEXT_TEMPIMPL(flext_hdr *FLEXT_CLASSDEF(flext_obj))::obj_new(const t_symbol *s,int _argc_,t_atom *argv) #endif { Locker lock; flext_hdr *obj = NULL; FLEXT_TEMPINST(flext_class) *lo = FindName(s); if(lo) { // post("NEWOBJ %s = %p -> %p",GetString(s),lo,lo->clss); bool ok = true; t_atom args[NEWARGS]; int argc = _argc_; if(lo->attr) { argc = flext_base::CheckAttrib(argc,argv); } if(lo->argc >= 0) { #ifdef FLEXT_DEBUG if(lo->argc > FLEXT_MAXNEWARGS) { ERRINTERNAL(); ok = false; } #endif int misnum = 0; if(argc > lo->argc) { ok = false; misnum = 1; } for(int i = 0; ok && i < lo->argc; ++i) { switch(lo->argv[i]) { #if FLEXT_SYS != FLEXT_SYS_PD case FLEXTTPN_INT: case FLEXTTPN_DEFINT: if(i >= argc) if(lo->argv[i] == FLEXTTPN_DEFINT) SetInt(args[i],0); else { misnum = -1; ok = false; break; } else if(IsInt(argv[i])) args[i] = argv[i]; else if(IsFloat(argv[i])) SetInt(args[i],(int)GetFloat(argv[i])); else ok = false; break; #endif case FLEXTTPN_FLOAT: case FLEXTTPN_DEFFLOAT: if(i >= argc) if(lo->argv[i] == FLEXTTPN_DEFFLOAT) SetFloat(args[i],0); else { misnum = -1; ok = false; break; } else if(IsInt(argv[i])) SetFloat(args[i],(float)GetInt(argv[i])); else if(IsFloat(argv[i])) args[i] = argv[i]; else ok = false; break; case FLEXTTPN_SYM: case FLEXTTPN_DEFSYM: // \todo shall we analyze the patcher args????... should already be done! if(i >= argc) if(lo->argv[i] == FLEXTTPN_DEFSYM) SetSymbol(args[i],sym__); else { misnum = -1; ok = false; break; } else if(IsSymbol(argv[i])) // SetSymbol(args[i],GetParamSym(GetSymbol(argv[i]),NULL)); args[i] = argv[i]; else ok = false; break; } } if(!ok) { if(misnum) error("%s: %s creation arguments",GetString(s),misnum < 0?"Not enough":"Too many"); else error("%s: Creation arguments do not match",GetString(s)); } } if(ok) { flext_obj::initing = true; try { #if FLEXT_SYS == FLEXT_SYS_PD obj = (flext_hdr *)::pd_new(lo->clss); #elif FLEXT_SYS == FLEXT_SYS_MAX obj = (flext_hdr *)::newobject(lo->clss); #else #error #endif flext_obj::m_holder = obj; flext_obj::m_holdclass = lo; flext_obj::m_holdname = s; flext_obj::init_ok = true; // get actual flext object (newfun calls "new flext_obj()") if(lo->argc >= 0) obj->data = lo->newfun(lo->argc,args); else obj->data = lo->newfun(argc,argv); flext_obj::m_holder = NULL; flext_obj::m_holdclass = NULL; flext_obj::m_holdname = NULL; ok = obj->data && // check constructor exit flag flext_obj::init_ok; if(ok) { if(lo->attr) { // DON'T convert eventual patcher args here... this is done by the actual attribute stuff // so that the initial $- or #- be preserved! // store creation args for attribute initialization (inside flext_base::Init()) flext_obj::m_holdaargc = _argc_-argc; flext_obj::m_holdaargv = argv+argc; } else { flext_obj::m_holdaargc = 0; flext_obj::m_holdaargv = NULL; } // call virtual init function // here, inlets, outlets, methods and attributes can be set up ok = obj->data->Init(); flext_obj::initing = false; // call another virtual init function if(ok) ok = obj->data->Finalize(); flext_obj::m_holdaargc = 0; flext_obj::m_holdaargv = NULL; } } //try catch(std::exception &x) { error("%s - Exception while creating object: %s",GetString(s),x.what()); ok = false; } catch(char *txt) { error("%s - Exception while creating object: %s",GetString(s),txt); ok = false; } catch(...) { error("%s - Unknown exception while creating object",GetString(s)); ok = false; } flext_obj::initing = false; if(ok) { #if FLEXT_SYS == FLEXT_SYS_MAX // create object-specific thread lock critical_new(&obj->data->lock); #endif } else { // there was some init error, free object lo->freefun(obj); obj = NULL; } } } #ifdef FLEXT_DEBUG else #if FLEXT_SYS == FLEXT_SYS_MAX // in Max/MSP an object with the name of the library exists, even if not explicitly declared! // if(!lo->lib || s != lo->lib->name) #endif error("Class %s not found in library!",s->s_name); #endif return obj; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_obj))::obj_free(flext_hdr *h) { Locker lock; flext_hdr *hdr = (flext_hdr *)h; const t_symbol *name = hdr->data->thisNameSym(); FLEXT_TEMPINST(flext_class) *lcl = FindName(name); if(lcl) { flext_obj::exiting = true; try { // call virtual exit function hdr->data->Exit(); #if FLEXT_SYS == FLEXT_SYS_MAX // free object-specific thread lock critical_free(hdr->data->lock); #endif // now call object destructor and deallocate lcl->freefun(hdr); } catch(std::exception &x) { error("%s - Exception while destroying object: %s",GetString(name),x.what()); } catch(char *txt) { error("%s - Exception while destroying object: %s",GetString(name),txt); } catch(...) { error("%s - Unknown exception while destroying object",GetString(name)); } flext_obj::exiting = false; } #ifdef FLEXT_DEBUG else #if FLEXT_SYS == FLEXT_SYS_MAX // in Max/MSP an object with the name of the library exists, even if not explicitly declared! // if(!lo->lib || s != lo->lib->name) #endif error("Class %s not found in library!",name); #endif } FLEXT_TEMPIMPL(t_class *FLEXT_CLASSDEF(flext_obj))::thisClass() const { FLEXT_ASSERT(x_obj); return thisClassId()->clss; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::SetDist(t_classid c,bool d) { c->dist = d; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::DoDist() const { return thisClassId()->dist; } FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext_base))::ItemCont *FLEXT_CLASSDEF(flext_base))::ClMeths(t_classid c) { return &c->meths; } FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext_base))::ItemCont *FLEXT_CLASSDEF(flext_base))::ClAttrs(t_classid c) { return &c->attrs; } #include "flpopns.h" #endif // __FLEXT_LIB_CPP flext-0-6-3/source/flmap.cpp000066400000000000000000000127531446466241400157660ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flmap.cpp \brief flext container classes. */ #ifndef __FLEXT_MAP_CPP #define __FLEXT_MAP_CPP #include "flext.h" #include "flmap.h" #include "flpushns.h" FLEXT_TEMPIMPL(TableAnyMap)::~TableAnyMap() { clear(); } FLEXT_TEMPIMPL(void TableAnyMap)::clear() { if(left) { _delmap(left); left = NULL; } if(right) { _delmap(right); right = NULL; } n = 0; } FLEXT_TEMPIMPL(void *TableAnyMap)::_set(int tsize,size_t k,void *t) { FLEXT_ASSERT(n); if(n < tsize) { // fall through } else if(k < data[0].key) return _toleft(tsize,k,t); else if(k > data[tsize-1].key) return _toright(tsize,k,t); int ix = _tryix(k); if(ix >= n) { FLEXT_ASSERT(ix == n); // after last entry data[n++](k,t); return NULL; } size_t dk = data[ix].key; if(k == dk) { // update data in existing slot (same key) void *a = data[ix].value; data[ix] = t; return a; } else { // insert new slot by shifting the higher ones FLEXT_ASSERT(k < dk); void *a; if(n == tsize) a = _toright(tsize,data[tsize-1]); else { ++n; a = NULL; } Data *tg = data+ix; for(Data *d = data+n-1; d > tg; d--) d[0] = d[-1]; (*tg)(k,t); return a; } } FLEXT_TEMPIMPL(void *TableAnyMap)::_find(int tsize,size_t k) const { FLEXT_ASSERT(n); if(n < tsize) { // fall through } else if(k < data[0].key) return left?left->_find(tsize,k):NULL; else if(k > data[n-1].key) return right?right->_find(tsize,k):NULL; const int ix = _tryix(k); return ix < n && data[ix].key == k?data[ix].value:NULL; } #ifdef FLEXT_DEBUG FLEXT_TEMPIMPL(void TableAnyMap)::_check(int tsize) { FLEXT_ASSERT(n); size_t k = data[0].key; for(int i = 1; i < n; ++i) { size_t k2 = data[i].key; FLEXT_ASSERT(k < k2); k = k2; } if(left || right) FLEXT_ASSERT(n == tsize); if(left) { FLEXT_ASSERT(flext::MemCheck(left)); left->_check(tsize); } if(right) { FLEXT_ASSERT(flext::MemCheck(right)); right->_check(tsize); } } #endif FLEXT_TEMPIMPL(void *TableAnyMap)::_remove(int tsize,size_t k) { FLEXT_ASSERT(n); if(n < tsize) { // fall through } else if(k < data[0].key) { void *r = left?left->_remove(tsize,k):NULL; if(r) _eraseempty(left); return r; } else if(k > data[n-1].key) { void *r = right?right->_remove(tsize,k):NULL; if(r) _eraseempty(right); return r; } const int ix = _tryix(k); if(ix >= n || data[ix].key != k) return NULL; else { // found key in this map void *ret = data[ix].value; Data dt; bool fnd,ins = false; if(n >= tsize) { // if this table is full get fill-in elements from branches if(left) { // try to get biggest element from left branch left->_getbig(dt); _eraseempty(left); fnd = true; ins = true; } else if(right) { // try to get smallest element from right branch right->_getsmall(dt); _eraseempty(right); fnd = true; } else fnd = false; } else fnd = false; if(ins) { // insert smaller element from left for(int i = ix; i; --i) data[i] = data[i-1]; data[0] = dt; } else { // shift elements for(int i = ix+1; i < n; ++i) data[i-1] = data[i]; // insert bigger element from right or reduce table size if(fnd) data[n-1] = dt; else --n; } return ret; } } FLEXT_TEMPIMPL(void TableAnyMap)::_getbig(Data &dt) { FLEXT_ASSERT(n); if(right) { right->_getbig(dt); _eraseempty(right); } else { dt = data[n-1]; if(left) { for(int i = n-1; i; --i) data[i] = data[i-1]; left->_getbig(data[0]); _eraseempty(left); } else --n; } } FLEXT_TEMPIMPL(void TableAnyMap)::_getsmall(Data &dt) { FLEXT_ASSERT(n); if(left) { left->_getsmall(dt); _eraseempty(left); } else { dt = data[0]; for(int i = 1; i < n; ++i) data[i-1] = data[i]; if(right) { right->_getsmall(data[n-1]); _eraseempty(right); } else --n; } } FLEXT_TEMPIMPL(void TableAnyMap)::iterator::forward() { FLEXT_ASSERT(map || ix >= map->n); if(++ix >= map->n) { TableAnyMap *nmap; // we reached the end of the slots if(map->right) { // climb up one map = map->right; leftmost(); ix = 0; } else { // fall back for(;;) { nmap = map->parent; if(!nmap) break; // no parent if(nmap->left == map) { // ok, we are in front of the slots now ix = 0; map = nmap; break; } else { FLEXT_ASSERT(nmap->right == map); ix = (map = nmap)->n; } } } } } #include "flpopns.h" #endif // __FLEXT_MAP_CPP flext-0-6-3/source/flmap.h000066400000000000000000000143661446466241400154350ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flmap.h \brief special map class (faster and less memory-consuming than std::map) */ #ifndef __FLMAP_H #define __FLMAP_H #include "flprefix.h" /*! \defgroup FLEXT_SUPPORT Flext support classes @{ */ #include "flpushns.h" FLEXT_TEMPLATE class FLEXT_SHARE TableAnyMap { public: virtual TableAnyMap *_newmap(TableAnyMap *parent) = 0; virtual void _delmap(TableAnyMap *map) = 0; struct Data { void operator()(size_t k,void *v) { key = k,value = v; } void operator =(void *v) { value = v; } size_t key; void *value; }; protected: // constructor and destructor are protected so that they can't be directly instantiated TableAnyMap(TableAnyMap *p,Data *dt) : data(dt) , parent(p),left(0),right(0) , n(0) {} virtual ~TableAnyMap(); public: #if 0 // set 1 for asserting the map structure (very cpu-intensive!) void check(int tsize) { if(n) _check(tsize); } #else // void check(int tsize) {} #endif void *insert(int tsize,size_t k,void *t) { void *r; if(LIKELY(n)) r = _set(tsize,k,t); else { data[n++](k,t); r = 0; } // check(tsize); return r; } void *find(int tsize,size_t k) const { return LIKELY(n)?_find(tsize,k):0; } void *remove(int tsize,size_t k) { void *r = LIKELY(n)?_remove(tsize,k):0; // check(tsize); return r; } virtual void clear(); class FLEXT_SHARE iterator { public: iterator(): map(0) {} iterator(const TableAnyMap &m): map(&m),ix(0) { leftmost(); } iterator(const iterator &it): map(it.map),ix(it.ix) {} iterator &operator =(const iterator &it) { map = it.map,ix = it.ix; return *this; } operator bool() const { return map && ix < map->n; } // no checking here! void *data() const { return map->data[ix].value; } size_t key() const { return map->data[ix].key; } iterator &operator ++() { forward(); return *this; } protected: void leftmost() { // search smallest branch (go left as far as possible) const TableAnyMap *nmap; while((nmap = map->left) != 0) map = nmap; } void forward(); // pointers to map and index within const TableAnyMap *map; int ix; }; void _init(size_t k,void *t) { data[0](k,t); n = 1; } void *_toleft(int tsize,size_t k,void *t) { if(left) return left->_set(tsize,k,t); else { (left = _newmap(this))->_init(k,t); return 0; } } void *_toright(int tsize,size_t k,void *t) { if(right) return right->_set(tsize,k,t); else { (right = _newmap(this))->_init(k,t); return 0; } } void *_toleft(int tsize,Data &v) { return _toleft(tsize,v.key,v.value); } void *_toright(int tsize,Data &v) { return _toright(tsize,v.key,v.value); } void *_set(int tsize,size_t k,void *t); void *_find(int tsize,size_t k) const; void *_remove(int tsize,size_t k); #ifdef FLEXT_DEBUG void _check(int tsize); #endif Data *data; TableAnyMap *parent,*left,*right; int n; //! return index of data item with key <= k //! \note index can point past the last item! unsigned int _tryix(size_t k) const { unsigned int ix = 0,b = n; while(ix != b) { const unsigned int c = (ix+b)>>1; const size_t dk = data[c].key; if(k == dk) return c; else if(k < dk) b = c; else if(ix < c) ix = c; else return b; } return ix; } void _eraseempty(TableAnyMap *&b) { if(!b->n) { // remove empty branch _delmap(b); b = 0; } } void _getsmall(Data &dt); void _getbig(Data &dt); private: // hide, so that it can't be used..... explicit TableAnyMap(const TableAnyMap &): data(NULL) {} TableAnyMap &operator =(const TableAnyMap &) { return *this; } }; template class TablePtrMap : #if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__) || defined(__MWERKS__) public // necessary for VC6 #endif FLEXT_TEMPINST(TableAnyMap) { public: TablePtrMap(): TableAnyMap(0,slots),count(0) {} virtual ~TablePtrMap() { clear(); } virtual void clear() { TableAnyMap::clear(); count = 0; } inline int size() const { return count; } inline T insert(K k,T t) { void *d = TableAnyMap::insert(N,*(size_t *)&k,(void *)t); if(!d) ++count; return (T)d; } inline T find(K k) const { return (T)TableAnyMap::find(N,*(size_t *)&k); } inline T remove(K k) { void *d = TableAnyMap::remove(N,*(size_t *)&k); if(LIKELY(d)) --count; return (T)d; } class iterator : TableAnyMap::iterator { public: iterator() {} iterator(const TablePtrMap &m): TableAnyMap::iterator(m) {} iterator(const iterator &it): TableAnyMap::iterator(it) {} // this ugly syntax (cast to parent class) is needed for MSVC6 inline iterator &operator =(const iterator &it) { ((TableAnyMap::iterator &)*this) = it; return *this; } inline operator bool() const { return (bool)((TableAnyMap::iterator &)*this); } inline T data() const { return (T)(((TableAnyMap::iterator &)*this).data()); } inline K key() const { return (K)(((TableAnyMap::iterator &)*this).key()); } inline iterator &operator ++() { ++((TableAnyMap::iterator &)*this); return *this; } }; protected: TablePtrMap(TableAnyMap *p): TableAnyMap(p,slots),count(0) {} virtual TableAnyMap *_newmap(TableAnyMap *_parent) { return new TablePtrMap(_parent); } virtual void _delmap(TableAnyMap *map) { delete (TablePtrMap *)map; } int count; Data slots[N]; private: explicit TablePtrMap(const TableAnyMap &p) { FLEXT_UNUSED(p); } }; #include "flpopns.h" //! @} // FLEXT_SUPPORT #endif flext-0-6-3/source/flmeth.cpp000066400000000000000000000074671446466241400161540ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flmeth.cpp \brief Method processing of flext base class. */ #ifndef __FLEXT_METH_CPP #define __FLEXT_METH_CPP #include "flext.h" #include "flinternal.h" #include #include #include "flpushns.h" FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::MethItem::MethItem(AttrItem *conn): Item(conn),index(0), argc(0),args(NULL) ,fun(NULL) {} FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::MethItem::~MethItem() { if(args) delete[] args; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::MethItem::SetArgs(methfun _fun,int _argc,int *_args) { fun = _fun; if(args) delete[] args; argc = _argc,args = _args; } /*! \brief Add a method to the queue */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddMethod(ItemCont *ma,int inlet,const t_symbol *tag,methfun fun,int tp,...) { #ifdef FLEXT_LOG_MSGS post("addmethod %i:%s",inlet,GetString(tag)); #endif va_list marker; // at first just count the arg type list (in argc) int argc = 0; va_start(marker,tp); int *args = NULL,arg = tp; for(; arg != a_null; ++argc) arg = va_arg(marker,int); va_end(marker); if(argc > 0) { if(argc > FLEXT_MAXMETHARGS) { error("flext - method %s: only %i arguments are type-checkable: use variable argument list for more",tag?GetString(tag):"?",FLEXT_MAXMETHARGS); argc = FLEXT_MAXMETHARGS; } args = new int[argc]; va_start(marker,tp); int a = tp; for(int ix = 0; ix < argc; ++ix) { #ifdef FLEXT_DEBUG if(a == a_list && ix > 0) { ERRINTERNAL(); } #endif #if FLEXT_SYS == FLEXT_SYS_PD && defined(FLEXT_COMPATIBLE) if(a == a_pointer) { post("Pointer arguments are not allowed in compatibility mode"); } #endif args[ix] = a; a = va_arg(marker,int); } va_end(marker); } MethItem *mi = new MethItem; mi->index = ma->Members(); mi->SetArgs(fun,argc,args); ma->Add(mi,tag,inlet); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ListMethods(AtomList &la,int inlet) const { typedef TablePtrMap MethList; MethList list[2]; ItemCont *clmethhead = ClMeths(thisClassId()); int i; for(i = 0; i <= 1; ++i) { ItemCont *a = i?methhead:clmethhead; if(a && a->Contained(inlet)) { ItemSet &ai = a->GetInlet(inlet); for(FLEXT_TEMP_TYPENAME ItemSet::iterator as(ai); as; ++as) { for(Item *al = as.data(); al; al = al->nxt) { MethItem *aa = (MethItem *)al; // check it's not related to an attribute if(!aa->IsAttr()) { list[i].insert(aa->index,as.key()); break; } } } } } la((int)list[0].size()+(int)list[1].size()); int ix = 0; for(i = 0; i <= 1; ++i) for(MethList::iterator it(list[i]); it; ++it) SetSymbol(la[ix++],it.data()); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::cb_ListMethods(flext_base *c,int argc,const t_atom *argv) { Locker lock(c); if(c->HasAttributes() && (argc == 0 || (argc == 1 && CanbeInt(argv[0])))) { // defined in flsupport.cpp int inlet = argc?GetAInt(argv[0]):0; AtomListStatic<32> la; c->ListMethods(la,inlet); c->ToOutAnything(c->GetOutAttr(),sym_methods,la.Count(),la.Atoms()); return true; } else return false; } #include "flpopns.h" #endif // __FLEXT_METH_CPP flext-0-6-3/source/flmsg.cpp000066400000000000000000000264371446466241400160030ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flmsg.cpp \brief Message processing of flext base class. */ #ifndef __FLEXT_MSG_CPP #define __FLEXT_MSG_CPP #include "flext.h" #include "flpushns.h" FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::TryMethTag(Item *lst,const t_symbol *tag,int argc,const t_atom *argv) { for(; lst; lst = lst->nxt) { MethItem *m = (MethItem *)lst; // FLEXT_LOG3("found method tag %s: inlet=%i, argc=%i",GetString(tag),m->inlet,argc); if(m->attr) { // attributes are treated differently if(m->attr->IsGet()) return DumpAttrib(tag,m->attr); else return SetAttrib(tag,m->attr,argc,argv); } else { if(m->argc == 1) { if(m->args[0] == a_list) { // try list if(((methfun_V)m->fun)(this,argc,const_cast(argv))) return true; } else if(m->args[0] == a_any) { // try anything if(((methfun_A)m->fun)(this,tag,argc,const_cast(argv))) return true; } } // try matching number of args if(m->argc == argc) { int ix; t_any aargs[FLEXT_MAXMETHARGS]; bool ok = true; for(ix = 0; ix < argc && ok; ++ix) { switch(m->args[ix]) { case a_float: { if(IsFloat(argv[ix])) aargs[ix].ft = GetFloat(argv[ix]); else if(IsInt(argv[ix])) aargs[ix].ft = (float)GetInt(argv[ix]); else ok = false; if(ok) FLEXT_LOG2("int arg %i = %f",ix,aargs[ix].ft); break; } case a_int: { if(IsFloat(argv[ix])) aargs[ix].it = (int)GetFloat(argv[ix]); else if(IsInt(argv[ix])) aargs[ix].it = GetInt(argv[ix]); else ok = false; if(ok) FLEXT_LOG2("float arg %i = %i",ix,aargs[ix].it); break; } case a_symbol: { if(IsSymbol(argv[ix])) aargs[ix].st = GetSymbol(argv[ix]); else ok = false; if(ok) FLEXT_LOG2("symbol arg %i = %s",ix,GetString(aargs[ix].st)); break; } #if FLEXT_SYS == FLEXT_SYS_PD case a_pointer: { if(IsPointer(argv[ix])) aargs[ix].pt = (t_gpointer *)GetPointer(argv[ix]); else ok = false; break; } #endif default: error("Argument type illegal"); ok = false; } } if(ok && ix == argc) { switch(argc) { case 0: return ((methfun_0)m->fun)(this); case 1: return ((methfun_1)m->fun)(this,aargs[0]); case 2: return ((methfun_2)m->fun)(this,aargs[0],aargs[1]); case 3: return ((methfun_3)m->fun)(this,aargs[0],aargs[1],aargs[2]); case 4: return ((methfun_4)m->fun)(this,aargs[0],aargs[1],aargs[2],aargs[3]); case 5: return ((methfun_5)m->fun)(this,aargs[0],aargs[1],aargs[2],aargs[3],aargs[4]); default: FLEXT_ASSERT(false); } } } } } return false; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::TryMethAny(Item *lst,const t_symbol *s,int argc,const t_atom *argv) { for(; lst; lst = lst->nxt) { MethItem *m = (MethItem *)lst; if(!m->IsAttr() && m->argc == 1 && m->args[0] == a_any) { // FLEXT_LOG4("found any method for %s: inlet=%i, symbol=%s, argc=%i",GetString(m->tag),m->inlet,GetString(s),argc); if(((methfun_A)m->fun)(this,s,argc,const_cast(argv))) return true; } } return false; } /*! \brief Find a method item for a specific tag and arguments \remark All attributes are also stored in the method list and retrieved by a member of the method item */ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::FindMeth(int inlet,const t_symbol *s,int argc,const t_atom *argv) { Item *lst; ItemCont *clmethhead = ClMeths(thisClassId()); // search for exactly matching tag if(UNLIKELY(methhead) && (lst = methhead->FindList(s,inlet)) != NULL && TryMethTag(lst,s,argc,argv)) return true; if((lst = clmethhead->FindList(s,inlet)) != NULL && TryMethTag(lst,s,argc,argv)) return true; // if nothing found try any inlet if(UNLIKELY(methhead) && (lst = methhead->FindList(s,-1)) != NULL && TryMethTag(lst,s,argc,argv)) return true; if((lst = clmethhead->FindList(s,-1)) != NULL && TryMethTag(lst,s,argc,argv)) return true; return false; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::FindMethAny(int inlet,const t_symbol *s,int argc,const t_atom *argv) { Item *lst; ItemCont *clmethhead = ClMeths(thisClassId()); if(UNLIKELY(methhead) && (lst = methhead->FindList(sym_anything,inlet)) != NULL && TryMethAny(lst,s,argc,argv)) return true; if((lst = clmethhead->FindList(sym_anything,inlet)) != NULL && TryMethAny(lst,s,argc,argv)) return true; // if nothing found try any inlet if(UNLIKELY(methhead) && (lst = methhead->FindList(sym_anything,-1)) != NULL && TryMethAny(lst,s,argc,argv)) return true; if((lst = clmethhead->FindList(sym_anything,-1)) != NULL && TryMethAny(lst,s,argc,argv)) return true; return false; } /*! \brief All the message processing The messages of all the inlets go here and are promoted to the registered callback functions */ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::CbMethodHandler(int inlet,const t_symbol *s,int argc,const t_atom *argv) { static bool trap = false; bool ret; curtag = s; #ifdef FLEXT_LOG_MSGS post("methodmain inlet:%i args:%i symbol:%s",inlet,argc,s?GetString(s):""); #endif try { ret = FindMeth(inlet,s,argc,argv); #ifdef FLEXT_LOG_MSGS if(ret) post("found %s message in %s,%i",GetString(s),__FILE__,__LINE__); #endif if(ret) goto end; if(argc == 1) { if(s == sym_list) { // for 1-element lists try the single atom (this is the format output by [route]) if(IsFloat(argv[0])) ret = FindMeth(inlet,sym_float,1,argv); else if(IsInt(argv[0])) ret = FindMeth(inlet,sym_int,1,argv); else if(IsSymbol(argv[0])) ret = FindMeth(inlet,sym_symbol,1,argv); #if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_COMPATIBLE) else if(IsPointer(argv[0])) ret = FindMeth(inlet,sym_pointer,1,argv); #endif if(ret) goto end; } else { if(s == sym_float) { #if FLEXT_SYS == FLEXT_SYS_MAX t_atom at; // If float message is not explicitly handled: try int handler instead SetInt(at,(int)GetFloat(argv[0])); ret = FindMeth(inlet,sym_int,1,&at); if(ret) goto end; #endif // If not explicitly handled: try list handler instead ret = FindMeth(inlet,sym_list,1,argv); if(ret) goto end; } #if FLEXT_SYS == FLEXT_SYS_MAX else if(s == sym_int) { t_atom at; // If int message is not explicitly handled: try float handler instead SetFloat(at,(float)GetInt(argv[0])); ret = FindMeth(inlet,sym_float,1,&at); if(ret) goto end; // If not explicitly handled: try list handler instead ret = FindMeth(inlet,sym_list,1,argv); if(ret) goto end; } #endif else if(s == sym_symbol) { ret = FindMeth(inlet,sym_list,1,argv); if(ret) goto end; } #if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_COMPATIBLE) else if(s == sym_pointer) { ret = FindMeth(inlet,sym_list,1,argv); if(ret) goto end; } #endif } } else if(argc == 0) { // If symbol message (pure anything without args) is not explicitly handled: try list handler instead if(s == sym_bang) // bang is equal to an empty list ret = FindMeth(inlet,sym_list,0,NULL); else { t_atom at; SetSymbol(at,s); ret = FindMeth(inlet,sym_list,1,&at); } #ifdef FLEXT_LOG_MSGS if(ret) post("found %s message in %s,%i",GetString(sym_list),__FILE__,__LINE__); #endif if(ret) goto end; } // if distmsgs is switched on then distribute list elements over inlets (Max/MSP behavior) if(DoDist() && inlet == 0 && s == sym_list && insigs <= 1 && !trap) { int i = incnt; if(i > argc) i = argc; for(--i; i >= 0; --i) { // right to left distribution const t_symbol *sym = NULL; if(IsFloat(argv[i])) sym = sym_float; else if(IsInt(argv[i])) sym = sym_int; else if(IsSymbol(argv[i])) sym = sym_symbol; #if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_COMPATIBLE) else if(IsPointer(argv[i])) sym = sym_pointer; // can pointer atoms occur here? #endif if(sym) { trap = true; CbMethodHandler(i,sym,1,argv+i); trap = false; } } goto end; } ret = FindMethAny(inlet,s,argc,argv); if(!ret) ret = CbMethodResort(inlet,s,argc,argv); } catch(std::exception &x) { error("%s - %s: %s",thisName(),GetString(s),x.what()); ret = false; } catch(const char *txt) { error("%s - %s: %s",thisName(),GetString(s),txt); ret = false; } catch(...) { error("%s - %s : Unknown exception while processing method",thisName(),GetString(s)); ret = false; } end: curtag = NULL; return ret; // true if appropriate handler was found and called } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::m_method_(int inlet,const t_symbol *s,int argc,const t_atom *argv) { FLEXT_UNUSED(argv); // keep compiler quiet post("%s: message unhandled - inlet:%i args:%i symbol:%s",thisName(),inlet,argc,s?GetString(s):""); return false; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::CbMethodResort(int inlet,const t_symbol *s,int argc,const t_atom *argv) { // call deprecated version return m_method_(inlet,s,argc,argv); } #include "flpopns.h" #endif // __FLEXT_MSG_CPP flext-0-6-3/source/flmspbuffer.h000066400000000000000000000047251446466241400166470ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flmspbuffer.h \brief Definition of the Max/MSP buffer structure \internal This file comes from David Zicarellis inofficial package index.sit The latter is not easily found so i included the original file buffer.h with flext */ #if (FLEXT_SYS == FLEXT_SYS_MAX) && !defined(__FLEXT_MSPBUFFER_H) #define __FLEXT_MSPBUFFER_H enum { MAXCHAN = 4 }; enum { bi_basefreq = 0, bi_detune, bi_lowfreq, bi_hifreq, bi_lowvel, bi_hivel, bi_gain, bi_numparams }; typedef struct _buffer { t_object b_obj; // doesn't have any signals so it doesn't need to be pxobject long b_valid; // flag is off during read replacement or editing operation float *b_samples; // stored with interleaved channels if multi-channel long b_frames; // number of sample frames (each one is sizeof(float) * b_nchans bytes) long b_nchans; // number of channels long b_size; // size of buffer in floats float b_sr; // sampling rate of the buffer float b_1oversr; // 1 / sr float b_msr; // sr * .001 // Mac-specific stuff float *b_memory; // pointer to where memory starts (initial padding for interp) t_symbol *b_name; short b_vol; short b_space; // looping info (from AIFF file) long b_susloopstart; // in samples long b_susloopend; // in samples long b_relloopstart; // in samples long b_relloopend; // in samples // instrument info (from AIFF file) short b_inst[bi_numparams]; // window stuff void *b_wind; double b_pixperfr; double b_frperpix; long b_imagesize; Point b_scroll; long b_scrollscale; long b_selbegin[MAXCHAN]; long b_selend[MAXCHAN]; long b_zoom; long b_zim[11]; void *b_mouseout; long b_format; // 'AIFF' or 'Sd2f' t_symbol *b_filename; // last file read (not written) for readagain message long b_oldnchans; // used for resizing window in case of # of channels change void *b_doneout; long b_outputbytes; // number of bytes used for output sample (1-4) long b_modtime; // last modified time ("dirty" method) } t_buffer; #define BUFWIND(x) ((t_wind *)(x->b_wind)) #endif flext-0-6-3/source/flout.cpp000066400000000000000000000262661446466241400160240ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flout.cpp \brief Implementation of the flext outlet functionality. */ #ifndef __FLEXT_OUT_CPP #define __FLEXT_OUT_CPP #include "flext.h" #include "flinternal.h" #include #include "flpushns.h" #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToSysAtom(int n,const t_atom &at) const { outlet *o = GetOut(n); if(LIKELY(o)) { CRITON(); if(IsSymbol(at)) outlet_symbol((t_outlet *)o,const_cast(GetSymbol(at))); else if(IsFloat(at)) outlet_float((t_outlet *)o,GetFloat(at)); #if FLEXT_SYS == FLEXT_SYS_MAX else if(IsInt(at)) outlet_flint((t_outlet *)o,GetInt(at)); #endif #if FLEXT_SYS == FLEXT_SYS_PD else if(IsPointer(at)) outlet_pointer((t_outlet *)o,GetPointer(at)); #endif else error("Atom type not supported"); CRITOFF(); } } #else #error Not implemented #endif #if defined(FLEXT_THREADS) #if FLEXT_QMODE == 2 #define CHKTHR() (LIKELY((!IsThreadRegistered() || IsThread(flext::thrmsgid)) && !InDSP())) #else #define CHKTHR() (LIKELY(!IsThreadRegistered() && !InDSP())) #endif #else #define CHKTHR() (LIKELY(!InDSP())) #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToOutBang(int n) const { if(CHKTHR()) ToSysBang(n); else ToQueueBang(n); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToOutFloat(int n,float f) const { if(CHKTHR()) ToSysFloat(n,f); else ToQueueFloat(n,f); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToOutInt(int n,int f) const { if(CHKTHR()) ToSysInt(n,f); else ToQueueInt(n,f); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToOutSymbol(int n,const t_symbol *s) const { if(CHKTHR()) ToSysSymbol(n,s); else ToQueueSymbol(n,s); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToOutAtom(int n,const t_atom &at) const { if(CHKTHR()) ToSysAtom(n,at); else ToQueueAtom(n,at); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToOutList(int n,int argc,const t_atom *argv) const { if(CHKTHR()) ToSysList(n,argc,argv); else ToQueueList(n,argc,argv); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToOutAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { if(CHKTHR()) ToSysAnything(n,s,argc,argv); else ToQueueAnything(n,s,argc,argv); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ToOutMsg(MsgBundle *mb) { if(CHKTHR()) ToSysMsg(mb); else ToQueueMsg(mb); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::Forward(const t_symbol *recv,const t_symbol *s,int argc,const t_atom *argv) { return CHKTHR()?SysForward(recv,s,argc,argv):QueueForward(recv,s,argc,argv); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::InitInlets() { bool ok = true; // incnt has number of inlets (any type) // insigs should be 0 FLEXT_ASSERT(!insigs && !inlets); // ---------------------------------- // create inlets // ---------------------------------- #if FLEXT_SYS == FLEXT_SYS_MAX // copy inlet descriptions indesc = new char *[incnt]; for(int i = 0; i < incnt; ++i) { xlet &x = inlist[i]; indesc[i] = x.desc; x.desc = NULL; } #endif #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX inlets = incnt > 1?new px_object *[incnt-1]:NULL; #endif // type info is now in list array #if FLEXT_SYS == FLEXT_SYS_PD { int cnt = 0; if(incnt >= 1) { xlet &xi = inlist[0]; // points to first inlet if(xi.tp == xlet_sig) ++insigs; // else leftmost inlet is already there... ++cnt; #if PD_MINOR_VERSION >= 37 && defined(PD_DEVEL_VERSION) // set tooltip // this is on a per-class basis... we cannot really use it here // if(xi.desc && *xi.desc) class_settip(thisClass(),gensym(xi.desc)); #endif } for(int ix = 1; ix < incnt; ++ix,++cnt) { xlet &xi = inlist[ix]; // points to first inlet t_inlet *in = NULL; switch(xi.tp) { case xlet_float: case xlet_int: { if(ix > 9) { // proxy inlet needed (inlets[ix-1] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages in = inlet_new(&x_obj->obj,&inlets[ix-1]->obj.ob_pd, (t_symbol *)sym_float, (t_symbol *)sym_float); } else { inlets[ix-1] = NULL; static char sym[] = " ft ?"; sym[4] = '0'+ix; in = inlet_new(&x_obj->obj, &x_obj->obj.ob_pd, (t_symbol *)sym_float, gensym(sym)); } break; } case xlet_sym: (inlets[ix-1] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages in = inlet_new(&x_obj->obj,&inlets[ix-1]->obj.ob_pd, (t_symbol *)sym_symbol, (t_symbol *)sym_symbol); break; case xlet_list: (inlets[ix-1] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages in = inlet_new(&x_obj->obj,&inlets[ix-1]->obj.ob_pd, (t_symbol *)sym_list, (t_symbol *)sym_list); break; case xlet_any: (inlets[ix-1] = (px_object *)pd_new(px_class))->init(this,ix); // proxy for 2nd inlet messages in = inlet_new(&x_obj->obj,&inlets[ix-1]->obj.ob_pd, 0, 0); break; case xlet_sig: inlets[ix-1] = NULL; #ifdef FLEXT_COMPATIBLE if(inlist[ix-1].tp != xlet_sig) { post("%s: All signal inlets must be left-aligned in compatibility mode",thisName()); ok = false; } else #endif { // pd is not able to handle signals and messages into the same inlet... in = inlet_new(&x_obj->obj, &x_obj->obj.ob_pd, (t_symbol *)sym_signal, (t_symbol *)sym_signal); ++insigs; } break; default: inlets[ix-1] = NULL; error("%s: Wrong type for inlet #%i: %i",thisName(),ix,(int)inlist[ix].tp); ok = false; } #if PD_MINOR_VERSION >= 37 && defined(PD_DEVEL_VERSION) // set tooltip if(in && xi.desc && *xi.desc) inlet_settip(in,gensym(xi.desc)); #endif } incnt = cnt; } #elif FLEXT_SYS == FLEXT_SYS_MAX { int ix,cnt; // count leftmost signal inlets while(insigs < incnt && inlist[insigs].tp == xlet_sig) ++insigs; for(cnt = 0,ix = incnt-1; ix >= insigs; --ix,++cnt) { xlet &xi = inlist[ix]; if(!ix) { if(xi.tp != xlet_any) { error("%s: Leftmost inlet must be of type signal or anything",thisName()); ok = false; } } else { FLEXT_ASSERT(inlets); switch(xi.tp) { case xlet_sig: inlets[ix-1] = NULL; error("%s: All signal inlets must be left-aligned",thisName()); ok = false; break; case xlet_float: { if(ix < 10) { inlets[ix-1] = NULL; floatin(x_obj,ix); break; } else goto makeproxy; } case xlet_int: { if(ix < 10) { inlets[ix-1] = NULL; intin(x_obj,ix); break; } else goto makeproxy; } makeproxy: case xlet_any: // non-leftmost case xlet_sym: case xlet_list: inlets[ix-1] = (px_object *)proxy_new(x_obj,ix,&((flext_hdr *)x_obj)->curinlet); break; default: inlets[ix-1] = NULL; error("%s: Wrong type for inlet #%i: %i",thisName(),ix,(int)xi.tp); ok = false; } } } if(inlets) while(ix >= 0) inlets[ix--] = NULL; } #else #error #endif return ok; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::InitOutlets() { bool ok = true; int procattr = HasAttributes()?1:0; // outcnt has number of inlets (any type) // outsigs should be 0 FLEXT_ASSERT(outsigs == 0); // ---------------------------------- // create outlets // ---------------------------------- #if FLEXT_SYS == FLEXT_SYS_MAX // for Max/MSP the rightmost outlet has to be created first outlet *attrtmp = NULL; if(procattr) attrtmp = (outlet *)newout_anything(thisHdr()); #endif #if FLEXT_SYS == FLEXT_SYS_MAX // copy outlet descriptions outdesc = new char *[outcnt]; for(int i = 0; i < outcnt; ++i) { xlet &xi = outlist[i]; outdesc[i] = xi.desc; xi.desc = NULL; } #endif #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX if(outcnt+procattr) outlets = new outlet *[outcnt+procattr]; else outlets = NULL; // type info is now in list array #if FLEXT_SYS == FLEXT_SYS_PD for(int ix = 0; ix < outcnt; ++ix) #elif FLEXT_SYS == FLEXT_SYS_MAX for(int ix = outcnt-1; ix >= 0; --ix) #else #error #endif { switch(outlist[ix].tp) { case xlet_float: outlets[ix] = (outlet *)newout_float(&x_obj->obj); break; case xlet_int: outlets[ix] = (outlet *)newout_flint(&x_obj->obj); break; case xlet_sig: outlets[ix] = (outlet *)newout_signal(&x_obj->obj); ++outsigs; break; case xlet_sym: outlets[ix] = (outlet *)newout_symbol(&x_obj->obj); break; case xlet_list: outlets[ix] = (outlet *)newout_list(&x_obj->obj); break; case xlet_any: outlets[ix] = (outlet *)newout_anything(&x_obj->obj); break; default: ; #ifdef FLEXT_DEBUG ERRINTERNAL(); #endif ok = false; } } #else #error #endif #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX if(procattr) { // attribute dump outlet is the last one outlets[outcnt] = #if FLEXT_SYS == FLEXT_SYS_PD // attribute dump outlet is the last one (outlet *)newout_anything(&x_obj->obj); #elif FLEXT_SYS == FLEXT_SYS_MAX attrtmp; #endif } #endif return ok; } #include "flpopns.h" #endif // __FLEXT_OUT_CPP flext-0-6-3/source/flpopns.h000066400000000000000000000014111446466241400160020ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #ifdef FLEXT_USE_NAMESPACE #ifndef _FLEXT_IN_NAMESPACE #error flext namespace pop is unbalanced #endif #define __FLEXT_IN_NAMESPACE (_FLEXT_IN_NAMESPACE-1) #undef _FLEXT_IN_NAMESPACE #define _FLEXT_IN_NAMESPACE __FLEXT_IN_NAMESPACE #undef __FLEXT_IN_NAMESPACE #if _FLEXT_IN_NAMESPACE == 0 #if 1 //defined(FLEXT_SHARED) } // namespace using namespace flext_ns; #elif defined(__GNUC__) } // anonymous namespace (don't export symbols) #endif #undef _FLEXT_IN_NAMESPACE #endif #endif flext-0-6-3/source/flprefix.h000066400000000000000000000305711446466241400161510ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2017 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flprefix.h \brief Try to find out the platform. */ #ifndef __FLEXT_PREFIX_H #define __FLEXT_PREFIX_H // --- definitions for FLEXT_SYS --------------------- #define FLEXT_SYS_UNKNOWN 0 #ifndef FLEXT_SYS_MAX #define FLEXT_SYS_MAX 1 #else // already defined #undef FLEXT_SYS_MAX #define FLEXT_SYS_MAX 1 #define FLEXT_SYS FLEXT_SYS_MAX #endif #ifndef FLEXT_SYS_PD #define FLEXT_SYS_PD 2 #else // already defined #undef FLEXT_SYS_PD #define FLEXT_SYS_PD 2 #define FLEXT_SYS FLEXT_SYS_PD #endif // --- definitions for FLEXT_OS ---------------------- #define FLEXT_OS_UNKNOWN 0 #define FLEXT_OS_WIN 1 #define FLEXT_OS_MAC 2 #define FLEXT_OS_LINUX 3 #define FLEXT_OS_IRIX 4 // --- definitions for FLEXT_OS_API --------------------- #define FLEXT_OSAPI_UNKNOWN 0 #define FLEXT_OSAPI_UNIX_POSIX 1 #define FLEXT_OSAPI_MAC_CLASSIC 2 #define FLEXT_OSAPI_MAC_CARBON 3 #define FLEXT_OSAPI_MAC_MACH 4 #define FLEXT_OSAPI_WIN_NATIVE 5 // WIN32 Platform #define FLEXT_OSAPI_WIN_POSIX 6 // POSIX API (e.g. cygwin) // --- definitions for FLEXT_CPU --------------------- #define FLEXT_CPU_UNKNOWN 0 #define FLEXT_CPU_IA32 1 #define FLEXT_CPU_PPC 2 #define FLEXT_CPU_MIPS 3 #define FLEXT_CPU_ALPHA 4 #define FLEXT_CPU_IA64 5 // Itanium #define FLEXT_CPU_X86_64 6 // AMD-K8, EMT64 #define FLEXT_CPU_PPC64 7 // G5 in 64 bit mode // compatibility #define FLEXT_CPU_INTEL FLEXT_CPU_IA32 // --- definitions for FLEXT_THREADS ----------------- #define FLEXT_THR_POSIX 1 // pthreads #define FLEXT_THR_WIN32 2 // Win32 native #define FLEXT_THR_MP 3 // MacOS MPThreads // --------------------------------------------------- // support old definitions #ifndef FLEXT_SYS #if defined(MAXMSP) #define FLEXT_SYS FLEXT_SYS_MAX // #undef MAXMSP #elif defined(PD) #define FLEXT_SYS FLEXT_SYS_PD // #undef PD // #undef NT #endif #endif #if defined(_DEBUG) && !defined(FLEXT_DEBUG) #define FLEXT_DEBUG #endif // --------------------------------------------------- // Definition of supported real-time systems #if FLEXT_SYS == FLEXT_SYS_MAX || FLEXT_SYS == FLEXT_SYS_PD #else #error "System must be defined by either FLEXT_SYS_MAX or FLEXT_SYS_PD" #endif // Definition of OS/CPU #if defined(_MSC_VER) || (defined(__ICC) && (FLEXT_OS == FLEXT_OS_WIN || defined(_WIN32))) // Microsoft C++ // and Intel C++ (as guessed) #ifndef FLEXT_CPU #if defined(_M_AMD64) #define FLEXT_CPU FLEXT_CPU_X86_64 #elif defined(_M_IA64) #define FLEXT_CPU FLEXT_CPU_IA64 #elif defined(_M_IX86) #define FLEXT_CPU FLEXT_CPU_IA32 #elif defined(_M_PPC) #define FLEXT_CPU FLEXT_CPU_PPC #elif defined(_M_MRX000) #define FLEXT_CPU FLEXT_CPU_MIPS #elif defined(_M_ALPHA) #define FLEXT_CPU FLEXT_CPU_ALPHA #else #define FLEXT_CPU FLEXT_CPU_UNKNOWN #endif #endif #ifndef FLEXT_OS #if defined(_WIN32) || defined(_WIN64) #define FLEXT_OS FLEXT_OS_WIN #define FLEXT_OSAPI FLEXT_OSAPI_WIN_NATIVE #else #define FLEXT_OS FLEXT_OS_UNKNOWN #define FLEXT_OSAPI FLEXT_OSAPI_UNKNOWN #endif #endif #elif defined(__BORLANDC__) // Borland C++ #ifndef FLEXT_CPU #define FLEXT_CPU FLEXT_CPU_INTEL #endif #ifndef FLEXT_OS #define FLEXT_OS FLEXT_OS_WIN #define FLEXT_OSAPI FLEXT_OSAPI_WIN_NATIVE #else #define FLEXT_OSAPI FLEXT_OSAPI_UNKNOWN #endif #elif defined(__MWERKS__) // Metrowerks CodeWarrior #ifdef __MACH__ // quick fix for OSX Mach-O #ifdef __POWERPC__ #ifdef __LP64__ #define TARGET_CPU_PPC64 1 #else #define TARGET_CPU_PPC 1 #endif #else #ifdef __LP64__ #define TARGET_CPU_X86_64 1 #else #define TARGET_CPU_IA32 1 #endif #endif #define TARGET_OS_MAC 1 #define TARGET_API_MAC_OSX 1 #else #ifndef __CONDITIONALMACROS__ #include #endif #endif #ifndef FLEXT_CPU #if TARGET_CPU_X86_64 #define FLEXT_CPU FLEXT_CPU_X86_64 #elif TARGET_CPU_X86 #define FLEXT_CPU FLEXT_CPU_IA32 #elif TARGET_CPU_PPC64 #define FLEXT_CPU FLEXT_CPU_PPC64 #elif TARGET_CPU_PPC #define FLEXT_CPU FLEXT_CPU_PPC #elif TARGET_CPU_MIPS #define FLEXT_CPU FLEXT_CPU_MIPS #elif TARGET_CPU_ALPHA #define FLEXT_CPU FLEXT_CPU_ALPHA #else #define FLEXT_CPU FLEXT_CPU_UNKNOWN #endif #endif #ifndef FLEXT_OS #if TARGET_OS_MAC #define FLEXT_OS FLEXT_OS_MAC #elif TARGET_OS_WIN32 // assume Windows #define FLEXT_OS FLEXT_OS_WIN #else #define FLEXT_OS FLEXT_OS_UNKNOWN #endif #endif #ifndef FLEXT_OSAPI #if TARGET_API_MAC_MACH // this is for Mach-O // this has the precedence (MACH also supports Carbon, of course) #define FLEXT_OSAPI FLEXT_OSAPI_MAC_MACH #elif TARGET_API_MAC_CARBON // this is for CFM #define FLEXT_OSAPI FLEXT_OSAPI_MAC_CARBON #else #define FLEXT_OSAPI FLEXT_OSAPI_UNKNOWN #endif #endif // This is important for method and attribute callbacks #pragma enumsalwaysint on // This is important for everything #pragma bool on #elif defined(__GNUG__) || (defined(__ICC) && (FLEXT_OS == FLEXT_OS_LINUX || defined(linux) || defined(__linux__))) // GNU C++ // and Intel (as suggested by Tim Blechmann) #ifndef FLEXT_CPU #if defined(__x86_64__) #define FLEXT_CPU FLEXT_CPU_X86_64 #elif defined(_X86_) || defined(__i386__) || defined(__i586__) || defined(__i686__) #define FLEXT_CPU FLEXT_CPU_IA32 #elif defined(__ppc64__) #define FLEXT_CPU FLEXT_CPU_PPC64 #elif defined(__ppc__) #define FLEXT_CPU FLEXT_CPU_PPC #elif defined(__MIPS__) #define FLEXT_CPU FLEXT_CPU_MIPS #else #define FLEXT_CPU FLEXT_CPU_UNKNOWN #endif #endif #ifndef FLEXT_OS #if defined(linux) || defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__GNU__) #define FLEXT_OS FLEXT_OS_LINUX #elif defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__) #define FLEXT_OS FLEXT_OS_WIN #elif defined(__APPLE__) && defined(__MACH__) #define FLEXT_OS FLEXT_OS_MAC // how about IRIX?? #else #define FLEXT_OS FLEXT_OS_UNKNOWN #endif #endif #ifndef FLEXT_OSAPI #if FLEXT_OS == FLEXT_OS_MAC #define FLEXT_OSAPI FLEXT_OSAPI_MAC_MACH #elif FLEXT_OS == FLEXT_OS_WIN #if defined(__MINGW32__) #define FLEXT_OSAPI FLEXT_OSAPI_WIN_NATIVE #else #define FLEXT_OSAPI FLEXT_OSAPI_WIN_POSIX #endif #elif FLEXT_OS == FLEXT_OS_LINUX || FLEXT_OS == FLEXT_OS_IRIX #define FLEXT_OSAPI FLEXT_OSAPI_UNIX_POSIX #else #define FLEXT_OSAPI FLEXT_OSAPI_UNKNOWN #endif #endif #elif defined(__MRC__) && defined(MPW_CPLUS) // Apple MPW MrCpp #if __MRC__ < 0x500 #error Apple MPW MrCpp v.5.0.0 or later compiler required #endif #ifndef FLEXT_CPU #if defined(__POWERPC__) #define FLEXT_CPU FLEXT_CPU_PPC #else #define FLEXT_CPU FLEXT_CPU_UNKNOWN #endif #endif #ifndef FLEXT_OS #if defined(macintosh) #define FLEXT_OS FLEXT_OS_MAC #else #define FLEXT_OS FLEXT_OS_UNKNOWN #endif #endif #ifndef FLEXT_OSAPI #if FLEXT_OS == FLEXT_OS_MAC #define FLEXT_OSAPI FLEXT_OSAPI_MAC_CLASSIC #else #define FLEXT_OSAPI FLEXT_OSAPI_UNKNOWN #endif #endif #endif #if FLEXT_OS == FLEXT_OS_WIN // #pragma message("Compiling for Windows") #if FLEXT_SYS == FLEXT_SYS_MAX // #define WIN_VERSION 1 #elif FLEXT_SYS == FLEXT_SYS_PD // #define PD // #define NT #endif #elif FLEXT_OS == FLEXT_OS_LINUX // #pragma message("Compiling for Linux") #if FLEXT_SYS == FLEXT_SYS_PD // #define PD #else #error "Flext SYS/OS combination unknown" #endif #elif FLEXT_OS == FLEXT_OS_IRIX // #pragma message("Compiling for Irix") #if FLEXT_SYS == FLEXT_SYS_PD // #define PD #else #error "Flext SYS/OS combination unknown" #endif #elif FLEXT_OS == FLEXT_OS_MAC // #pragma message("Compiling for MacOS") #if FLEXT_SYS == FLEXT_SYS_PD // #define PD #endif #else #error "Operating system could not be determined" #endif #if FLEXT_SYS == FLEXT_SYS_MAX // #pragma message("Compiling for Max/MSP") #ifndef MSP64 #if FLEXT_CPU == FLEXT_CPU_X86_64 #define MSP64 1 #else #define MSP64 0 #endif #endif #elif FLEXT_SYS == FLEXT_SYS_PD // #pragma message("Compiling for PD") #endif // ----- set threading model ----- // shared builds are always threaded #ifdef FLEXT_SHARED #undef FLEXT_THREADS #define FLEXT_THREADS #endif #ifdef FLEXT_THREADS #undef FLEXT_THREADS #if FLEXT_SYS == FLEXT_SYS_MAX && FLEXT_OS == FLEXT_OS_MAC && FLEXT_OSAPI != FLEXT_OSAPI_MAC_MACH // Max for CFM doesn't like posix threads #define FLEXT_THREADS FLEXT_THR_MP #elif FLEXT_SYS == FLEXT_SYS_MAX && FLEXT_OS == FLEXT_OS_WIN // for wmax use native Windows threads #define FLEXT_THREADS FLEXT_THR_WIN32 #else #define FLEXT_THREADS FLEXT_THR_POSIX #endif #endif // ----- macros for class names ----- /* With linux (flat linker namespace) and more than one flext-based external loaded all calls to static exported functions refer to the first instance loaded! Therefore different class names are used so that the correct type of flext function is called. */ #ifdef __DOXYGEN__ #define FLEXT_CLASSDEF(CL) CL #elif defined(FLEXT_DEBUG) #if defined(FLEXT_SHARED) #define FLEXT_CLASSDEF(CL) CL##_shared_d #elif defined(FLEXT_THREADS) #define FLEXT_CLASSDEF(CL) CL##_multi_d #else #define FLEXT_CLASSDEF(CL) CL##_single_d #endif #else #if defined(FLEXT_SHARED) #define FLEXT_CLASSDEF(CL) CL##_shared #elif defined(FLEXT_THREADS) #define FLEXT_CLASSDEF(CL) CL##_multi #else #define FLEXT_CLASSDEF(CL) CL##_single #endif #endif /* Set the right calling convention (and exporting) for the OS */ #if defined(_MSC_VER) #ifdef FLEXT_SHARED // for compiling a shared flext library FLEXT_EXPORTS must be defined #ifdef FLEXT_EXPORTS #define FLEXT_SHARE __declspec(dllexport) #else #define FLEXT_SHARE __declspec(dllimport) #endif #else #define FLEXT_SHARE #endif #define FLEXT_EXT __declspec(dllexport) #else // other OS's #define FLEXT_SHARE #define FLEXT_EXT #endif // std namespace #ifdef __MWERKS__ # define STD std #else # define STD #endif // branching hints #if __GNUC__ >= 3 # ifndef LIKELY # define LIKELY(expression) (__builtin_expect(!!(expression), 1)) # endif # ifndef UNLIKELY # define UNLIKELY(expression) (__builtin_expect(!!(expression), 0)) # endif #else # ifndef LIKELY # define LIKELY(expression) (expression) # endif # ifndef UNLIKELY # define UNLIKELY(expression) (expression) # endif #endif // macro definitions for inline flext usage #ifdef FLEXT_INLINE # define FLEXT_TEMPLATE template # define FLEXT_TEMPIMPL(fun) template fun # define FLEXT_TEMPINST(fun) fun # define FLEXT_TEMPSUB(fun) typename fun # define FLEXT_TEMP_TYPENAME typename #else # define FLEXT_TEMPLATE # define FLEXT_TEMPIMPL(fun) fun # define FLEXT_TEMPINST(fun) fun # define FLEXT_TEMPSUB(fun) fun # define FLEXT_TEMP_TYPENAME #endif #endif // __FLEXT_PREFIX_H flext-0-6-3/source/flproxy.cpp000066400000000000000000000172601446466241400163700ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flproxy.cpp \brief Proxy classes for the flext base class. */ #ifndef __FLEXT_PROXY_CPP #define __FLEXT_PROXY_CPP #include "flext.h" #include "flinternal.h" #include "flpushns.h" // === proxy class for flext_base ============================ #if FLEXT_SYS == FLEXT_SYS_PD FLEXT_TEMPIMPL(t_class *FLEXT_CLASSDEF(flext_base))::px_class = NULL; FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::px_object::px_bang(px_object *obj) { Locker lock(obj->base); obj->base->CbMethodHandler(obj->index,sym_bang,0,NULL); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::px_object::px_float(px_object *obj,t_float f) { t_atom a; SetFloat(a,f); Locker lock(obj->base); obj->base->CbMethodHandler(obj->index,sym_float,1,&a); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::px_object::px_symbol(px_object *obj,const t_symbol *s) { t_atom a; SetSymbol(a,s); Locker lock(obj->base); obj->base->CbMethodHandler(obj->index,sym_symbol,1,&a); } /* FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::px_object::px_pointer(px_object *obj,const t_gpointer *p) { t_atom a; SetPointer(a,p); Locker lock(obj->base); obj->base->CbMethodHandler(obj->index,sym_pointer,1,&a); } */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::px_object::px_anything(px_object *obj,const t_symbol *s,int argc,t_atom *argv) { Locker lock(obj->base); obj->base->CbMethodHandler(obj->index,s,argc,argv); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_bang(flext_hdr *c) { Locker lock(c); thisObject(c)->CbMethodHandler(0,sym_bang,0,NULL); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_float(flext_hdr *c,t_float f) { t_atom a; SetFloat(a,f); Locker lock(c); thisObject(c)->CbMethodHandler(0,sym_float,1,&a); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_symbol(flext_hdr *c,const t_symbol *s) { t_atom a; SetSymbol(a,s); Locker lock(c); thisObject(c)->CbMethodHandler(0,sym_symbol,1,&a); } /* FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_pointer(flext_hdr *c,const t_gpointer *p) { t_atom a; SetPointer(a,p); Locker lock(c); thisObject(c)->CbMethodHandler(0,sym_pointer,1,&a); } */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_anything(flext_hdr *c,const t_symbol *s,int argc,t_atom *argv) { Locker lock(c); if(UNLIKELY(!s)) { // apparently, this happens only in one case... object is a DSP object, but has no main DSP inlet... // interpret tag from args if(!argc) s = sym_bang; else if(argc == 1) { if(IsFloat(*argv)) s = sym_float; else if(IsSymbol(*argv)) s = sym_symbol; else if(IsPointer(*argv)) s = sym_pointer; else FLEXT_ASSERT(false); } else s = sym_list; } thisObject(c)->CbMethodHandler(0,s,argc,argv); } #define DEF_PROXYMSG(IX) \ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_px_ft ## IX(flext_hdr *c,t_float v) { t_atom atom; SetFloat(atom,v); Locker lock(c); thisObject(c)->CbMethodHandler(IX,sym_float,1,&atom); } #define ADD_PROXYMSG(c,IX) \ add_method1(c,cb_px_ft ## IX," ft " #IX,A_FLOAT) //AddMethod(c,0,flext::MakeSymbol("ft" #IX),cb_px_ft ## IX) #elif FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_anything(flext_hdr *c,const t_symbol *s,short argc,t_atom *argv) { Locker lock(c); int const ci = proxy_getinlet((t_object *)&c->obj); // post("%s %i, cb_anything(%i)",__FILE__,__LINE__,ci); thisObject(c)->CbMethodHandler(ci,s,argc,argv); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_int(flext_hdr *c,long v) { t_atom atom; SetInt(atom,v); Locker lock(c); int const ci = proxy_getinlet((t_object *)&c->obj); thisObject(c)->CbMethodHandler(ci,sym_int,1,&atom); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_float(flext_hdr *c,double v) { t_atom atom; SetFloat(atom,v); Locker lock(c); int const ci = proxy_getinlet((t_object *)&c->obj); thisObject(c)->CbMethodHandler(ci,sym_float,1,&atom); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_bang(flext_hdr *c) { Locker lock(c); int const ci = proxy_getinlet((t_object *)&c->obj); thisObject(c)->CbMethodHandler(ci,sym_bang,0,NULL); } #define DEF_PROXYMSG(IX) \ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_px_in ## IX(flext_hdr *c,long v) { t_atom atom; SetInt(atom,v); Locker lock(c); thisObject(c)->CbMethodHandler(IX,sym_int,1,&atom); } \ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_px_ft ## IX(flext_hdr *c,double v) { t_atom atom; SetFloat(atom,v); Locker lock(c); thisObject(c)->CbMethodHandler(IX,sym_float,1,&atom); } /* FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_px_in ## IX(flext_hdr *c,long v) { t_atom atom; SetInt(atom,v); Locker lock(c); thisObject(c)->CbMethodHandler(IX,sym_int,1,&atom); } \ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::cb_px_ft ## IX(flext_hdr *c,double v) { t_atom atom; SetFloat(atom,v); Locker lock(c); thisObject(c)->CbMethodHandler(IX,sym_float,1,&atom); } */ #define ADD_PROXYMSG(c,IX) \ addinx((method)(cb_px_in ## IX),IX); \ addftx((method)(cb_px_ft ## IX),IX) /* add_method1(c,cb_px_in ## IX,"in" #IX,A_INT); \ add_method1(c,cb_px_ft ## IX,"ft" #IX,A_FLOAT) AddMethod(c,0,flext::MakeSymbol("in" #IX),cb_px_in ## IX); \ AddMethod(c,0,flext::MakeSymbol("ft" #IX),cb_px_ft ## IX) */ #endif #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX DEF_PROXYMSG(1) DEF_PROXYMSG(2) DEF_PROXYMSG(3) DEF_PROXYMSG(4) DEF_PROXYMSG(5) DEF_PROXYMSG(6) DEF_PROXYMSG(7) DEF_PROXYMSG(8) DEF_PROXYMSG(9) FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::SetProxies(t_class *c,bool dsp) { #if FLEXT_SYS == FLEXT_SYS_PD // for leftmost inlet class_addbang(c,cb_bang); if(!dsp) class_addfloat(c,cb_float); class_addsymbol(c,cb_symbol); // class_addpointer(c,cb_pointer); class_addlist(c,cb_anything); class_addanything(c,cb_anything); // proxy for extra inlets if(UNLIKELY(!px_class)) { // only once px_class = class_new(gensym(const_cast(" flext_base proxy ")),NULL,NULL,sizeof(px_object),CLASS_PD|CLASS_NOINLET, A_NULL); if(px_class) { class_addbang(px_class,px_object::px_bang); // for other inlets class_addfloat(px_class,px_object::px_float); // for other inlets class_addsymbol(px_class,px_object::px_symbol); // for other inlets // class_addpointer(px_class,px_object::px_pointer); // for other inlets class_addlist(px_class,px_object::px_anything); // for other inlets class_addanything(px_class,px_object::px_anything); // for other inlets } else { // NULL case not handled (dsp precision mismatch 32<>64 bits) } } #elif FLEXT_SYS == FLEXT_SYS_MAX addbang((method)cb_bang); addint((method)cb_int); addfloat((method)cb_float); addmess((method)cb_anything,const_cast("list"),A_GIMME,A_NOTHING); // must be explicitly given, otherwise list elements are distributed over inlets addmess((method)cb_anything,const_cast("anything"),A_GIMME,A_NOTHING); #else #error Not implemented! #endif // setup non-leftmost ints and floats ADD_PROXYMSG(c,1); ADD_PROXYMSG(c,2); ADD_PROXYMSG(c,3); ADD_PROXYMSG(c,4); ADD_PROXYMSG(c,5); ADD_PROXYMSG(c,6); ADD_PROXYMSG(c,7); ADD_PROXYMSG(c,8); ADD_PROXYMSG(c,9); } #endif #include "flpopns.h" #endif // __FLEXT_PROXY_CPP flext-0-6-3/source/flpushns.h000066400000000000000000000013051446466241400161650ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #ifdef FLEXT_USE_NAMESPACE #ifndef _FLEXT_IN_NAMESPACE #define _FLEXT_IN_NAMESPACE 0 #endif #if _FLEXT_IN_NAMESPACE == 0 #if 1 //defined(FLEXT_SHARED) namespace flext_ns { #elif defined(__GNUC__) namespace { // anonymous namespace (don't export symbols) #endif #endif #define __FLEXT_IN_NAMESPACE (_FLEXT_IN_NAMESPACE+1) #undef _FLEXT_IN_NAMESPACE #define _FLEXT_IN_NAMESPACE __FLEXT_IN_NAMESPACE #undef __FLEXT_IN_NAMESPACE #endif flext-0-6-3/source/flqueue.cpp000066400000000000000000000436301446466241400163330ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flqueue.cpp \brief Implementation of the flext message queuing functionality. \todo Let's see if queuing can be implemented for Max/MSP with defer_low if FLEXT_PDLOCK is defined, the new PD thread lock functions are used */ #ifndef __FLEXT_QUEUE_CPP #define __FLEXT_QUEUE_CPP #include "flext.h" #include "flinternal.h" #include "flcontainers.h" #include // for memcpy #include "flpushns.h" #ifdef FLEXT_THREADS //! Thread id of message queue thread FLEXT_TEMPIMPL(FLEXT_TEMPINST(FLEXT_CLASSDEF(flext))::thrid_t FLEXT_CLASSDEF(flext))::thrmsgid; #endif FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::qustarted = false; #ifdef FLEXT_SHARED /* For the shared version it _should_ be possible to have only one queue for all externals. Yet I don't know how to do this cross-platform */ #define PERMANENTIDLE #endif FLEXT_TEMPLATE void Trigger(); FLEXT_TEMPLATE class QueueFifo : public PooledFifo { public: ~QueueFifo(); }; FLEXT_TEMPLATE class Queue: public flext, public FLEXT_TEMPINST(QueueFifo) { public: inline bool Empty() const { return !Avail(); } void Push(MsgBundle *m); // defined after MsgBundle (gcc 3.3. won't take it otherwise...) }; FLEXT_TEMPLATE struct QVars { #if FLEXT_QMODE == 2 static flext::ThrCond *qthrcond; #elif FLEXT_QMODE == 0 static t_clock *qclk; #endif static FLEXT_TEMPINST(Queue) *queue; }; #if FLEXT_QMODE == 2 FLEXT_TEMPIMPL(flext::ThrCond *QVars)::qthrcond = NULL; #elif FLEXT_QMODE == 0 FLEXT_TEMPIMPL(t_clock *QVars)::qclk = NULL; #endif FLEXT_TEMPIMPL(FLEXT_TEMPINST(Queue) *QVars)::queue = NULL; #define STATSIZE 8 FLEXT_TEMPIMPL(class FLEXT_CLASSDEF(flext))::MsgBundle: public flext, public FifoCell { public: static MsgBundle *New() { MsgBundle *m = FLEXT_TEMPINST(QVars)::queue->New(); m->msg.Init(); return m; } static void Free(MsgBundle *m) { for(Msg *mi = m->msg.nxt; mi; ) { Msg *mn = mi->nxt; mi->Free(); delete mi; mi = mn; } m->msg.Free(); FLEXT_TEMPINST(QVars)::queue->Free(m); } bool BelongsTo(flext_base *t) const { return !msg.nxt && msg.BelongsTo(t); } void Idle(flext_base *t) { Get()->Idle(t); } void Idle(bool (*idlefun)(int argc,const t_atom *argv),int argc,const t_atom *argv) { Get()->Idle(idlefun,argc,argv); } inline MsgBundle &Add(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av) { Get()->Set(t,o,s,ac,av); return *this; } inline MsgBundle &Add(const t_symbol *r,const t_symbol *s,int ac,const t_atom *av) { Get()->Set(r,s,ac,av); return *this; } inline MsgBundle &Add(flext_base *th,int o) // bang { return Add(th,o,sym_bang,0,NULL); } inline MsgBundle &Add(flext_base *th,int o,float dt) { t_atom at; SetFloat(at,dt); return Add(th,o,sym_float,1,&at); } inline MsgBundle &Add(flext_base *th,int o,int dt) { t_atom at; SetInt(at,dt); const t_symbol *sym; #if FLEXT_SYS == FLEXT_SYS_PD sym = sym_float; #elif FLEXT_SYS == FLEXT_SYS_MAX sym = sym_int; #else #error Not implemented! #endif return Add(th,o,sym,1,&at); } inline MsgBundle &Add(flext_base *th,int o,const t_symbol *dt) { t_atom at; SetSymbol(at,dt); return Add(th,o,sym_symbol,1,&at); } inline MsgBundle &Add(flext_base *th,int o,const t_atom &a) { const t_symbol *sym; if(IsSymbol(a)) sym = sym_symbol; else if(IsFloat(a)) sym = sym_float; #if FLEXT_SYS == FLEXT_SYS_MAX else if(IsInt(a)) sym = sym_int; #endif #if FLEXT_SYS == FLEXT_SYS_PD else if(IsPointer(a)) sym = sym_pointer; #endif else { error("atom type not supported"); return *this; } return Add(th,o,sym,1,&a); } inline MsgBundle &Add(flext_base *th,int o,int ac,const t_atom *av) { return Add(th,o,sym_list,ac,av); } // \note PD sys lock must already be held by caller inline bool Send() const { if(!msg.Ok()) return false; // Empty! const Msg *m = &msg; do { if(m->Send()) { // we should re-enqeue the message... it can't be a real bundle then, only a solo message FLEXT_ASSERT(!m->nxt); return true; } m = m->nxt; } while(m); return false; } private: class Msg { public: inline bool Ok() const { return th || recv; } void Init() { th = NULL; recv = NULL; nxt = NULL; argc = 0; } void Free() { if(argc > STATSIZE) { FLEXT_ASSERT(argv); delete[] argv; } } //! Attention: works only for solo messages, not real bundles!! bool BelongsTo(flext_base *t) const { FLEXT_ASSERT(!nxt); return th == t; } void Set(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av) { FLEXT_ASSERT(t); th = t; out = o; SetMsg(s,ac,av); } void Set(const t_symbol *r,const t_symbol *s,int ac,const t_atom *av) { FLEXT_ASSERT(r); th = NULL; recv = r; SetMsg(s,ac,av); } void Idle(flext_base *t) { FLEXT_ASSERT(t); th = t; SetMsg(NULL,0,NULL); } void Idle(bool (*idlefun)(int,const t_atom *),int ac,const t_atom *av) { FLEXT_ASSERT(idlefun); th = NULL; fun = idlefun; SetMsg(NULL,ac,av); } bool Send() const { if(LIKELY(sym)) { // messages if(th) { if(UNLIKELY(out < 0)) // message to self th->CbMethodHandler(-1-out,sym,argc,argc > STATSIZE?argv:argl); else // message to outlet th->ToSysAnything(out,sym,argc,argc > STATSIZE?argv:argl); } else flext::SysForward(recv,sym,argc,argc > STATSIZE?argv:argl); return false; } else { // idle processing if(th) // call virtual method return th->CbIdle(); else // call static function return (*fun)(argc,argc > STATSIZE?argv:argl); } } Msg *nxt; protected: flext_base *th; union { int out; const t_symbol *recv; bool (*fun)(int argc,const t_atom *argv); }; const t_symbol *sym; int argc; union { t_atom *argv; t_atom argl[STATSIZE]; }; void SetMsg(const t_symbol *s,int cnt,const t_atom *lst) { sym = s; argc = cnt; if(UNLIKELY(cnt > STATSIZE)) { argv = new t_atom[cnt]; flext::CopyAtoms(cnt,argv,lst); } else flext::CopyAtoms(cnt,argl,lst); } } msg; Msg *Get() { Msg *m = &msg; if(LIKELY(m->Ok())) { for(; m->nxt; m = m->nxt) {} m = m->nxt = new Msg; m->Init(); } return m; } }; FLEXT_TEMPIMPL(QueueFifo)::~QueueFifo() { flext::MsgBundle *n; while((n = Get()) != NULL) delete n; } FLEXT_TEMPIMPL(void Queue)::Push(MsgBundle *m) { if(LIKELY(m)) { Put(m); FLEXT_TEMPINST(Trigger)(); } } #define CHUNK 10 #if FLEXT_QMODE == 1 FLEXT_TEMPLATE bool QWork(bool syslock,flext_base *flushobj = NULL) { // Since qcnt can only be increased from any other function than QWork // qc will be a minimum guaranteed number of present queue elements. // On the other hand, if new queue elements are added by the methods called // in the loop, these will be sent in the next tick to avoid recursion overflow. flext::MsgBundle *q; if((q = queue.Get()) == NULL) return false; else if(q->Send()) { if(!flushobj || !q->BelongsTo(flushobj)) queue.Push(q); // remember messages to be processed again else flext::MsgBundle::Free(q); return true; } else { flext::MsgBundle::Free(q); return false; } } #else FLEXT_TEMPLATE bool QWork(bool syslock,flext_base *flushobj = NULL) { FLEXT_UNUSED(syslock); // keep compiler quiet FLEXT_TEMPINST(Queue) newmsgs; flext::MsgBundle *q; #if 0 static int counter = 0; fprintf(stderr,"QWORK %i\n",counter++); #endif for(;;) { // Since qcnt can only be increased from any other function than QWork // qc will be a minimum guaranteed number of present queue elements. // On the other hand, if new queue elements are added by the methods called // in the loop, these will be sent in the next tick to avoid recursion overflow. if(!FLEXT_TEMPINST(QVars)::queue->Avail()) break; #if FLEXT_QMODE == 2 if(syslock) flext::Lock(); #endif while((q = FLEXT_TEMPINST(QVars)::queue->Get()) != NULL) { if(q->Send()) newmsgs.Push(q); // remember messages to be processed again else flext::MsgBundle::Free(q); } #if FLEXT_QMODE == 2 if(syslock) flext::Unlock(); #endif } // enqueue messages that have to be processed again while((q = newmsgs.Get()) != NULL) if(!flushobj || !q->BelongsTo(flushobj)) FLEXT_TEMPINST(QVars)::queue->Push(q); else flext::MsgBundle::Free(q); return FLEXT_TEMPINST(QVars)::queue->Avail(); } #endif #if FLEXT_QMODE == 0 FLEXT_TEMPLATE void QTick(flext_base *c) { FLEXT_UNUSED(c); // keep compiler quiet FLEXT_TEMPINST(QWork)(false); } #elif FLEXT_QMODE == 1 # ifndef PERMANENTIDLE static bool qtickactive = false; # endif FLEXT_TEMPLATE t_int QTick(t_int *) { #ifndef PERMANENTIDLE qtickactive = false; #endif if(QWork(false)) return 1; else { # ifdef PERMANENTIDLE // will be run in the next idle cycle return 2; # else // won't be run again // for non-shared externals assume that there's rarely a message waiting // so it's better to delete the callback meanwhile return 0; # endif } } #endif /* It would be sufficient to only flush messages belonging to object th But then the order of sent messages is not as intended */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::QFlush(flext_base *th) { FLEXT_ASSERT(!IsThreadRegistered()); while(!FLEXT_TEMPINST(QVars)::queue->Empty()) FLEXT_TEMPINST(QWork)(false,th); } FLEXT_TEMPLATE void Trigger() { #if FLEXT_SYS == FLEXT_SYS_PD # if FLEXT_QMODE == 2 // wake up worker thread FLEXT_TEMPINST(QVars)::qthrcond->Signal(); # elif FLEXT_QMODE == 1 && !defined(PERMANENTIDLE) if(!qtickactive) { sys_callback(FLEXT_TEMPINST(QTick),NULL,0); qtickactive = true; } # elif FLEXT_QMODE == 0 # ifdef FLEXT_THREADS bool sys = flext::IsThread(flext::GetSysThreadId()); # else bool sys = true; # endif if(!sys) flext::Lock(); clock_delay(FLEXT_TEMPINST(QVars)::qclk,0); if(!sys) flext::Unlock(); # endif #elif FLEXT_SYS == FLEXT_SYS_MAX # if FLEXT_QMODE == 0 // qelem_front(FLEXT_TEMPINST(QVars)::qclk); clock_delay(FLEXT_TEMPINST(QVars)::qclk,0); # endif #else # error Not implemented #endif } #if FLEXT_QMODE == 2 FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::QWorker(thr_params *) { thrmsgid = GetThreadId(); qustarted = true; for(;;) { // we need a timed wait so that idle processing can take place FLEXT_TEMPINST(QVars)::qthrcond->TimedWait(0.001); FLEXT_TEMPINST(QWork)(true); } } #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::StartQueue() { #if FLEXT_QMODE == 2 FLEXT_TEMPINST(QVars)::qthrcond = new FLEXT_CLASSDEF(flext)::ThrCond; #endif FLEXT_TEMPINST(QVars)::queue = new FLEXT_TEMPINST(Queue); if(qustarted) return; #if FLEXT_QMODE == 1 # ifdef PERMANENTIDLE sys_callback(FLEXT_TEMPINST(QTick),NULL,0); qustarted = true; # endif #elif FLEXT_QMODE == 2 LaunchThread(QWorker,NULL); // very unelegant... but waiting should be ok, since happens only on loading while(!qustarted) Sleep(0.001); #elif FLEXT_QMODE == 0 && (FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX) // qclk = (t_qelem *)(qelem_new(NULL,(t_method)FLEXT_TEMPINST(QTick))); FLEXT_TEMPINST(QVars)::qclk = (t_clock *)(clock_new(NULL,(t_method)FLEXT_TEMPINST(QTick))); qustarted = true; #else # error Not implemented! #endif } FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext))::MsgBundle *FLEXT_CLASSDEF(flext))::MsgNew() { return MsgBundle::New(); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::MsgFree(MsgBundle *m) { MsgBundle::Free(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ToSysMsg(MsgBundle *m) { m->Send(); FLEXT_TEMPINST(QVars)::queue->Free(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ToQueueMsg(MsgBundle *m) { FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueBang(int o) const { MsgBundle *m = MsgBundle::New(); m->Add(const_cast(this),o); FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueFloat(int o,float f) const { MsgBundle *m = MsgBundle::New(); m->Add(const_cast(this),o,f); FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueInt(int o,int f) const { MsgBundle *m = MsgBundle::New(); m->Add(const_cast(this),o,f); FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueSymbol(int o,const t_symbol *s) const { MsgBundle *m = MsgBundle::New(); m->Add(const_cast(this),o,s); FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueAtom(int o,const t_atom &at) const { MsgBundle *m = MsgBundle::New(); m->Add(const_cast(this),o,at); FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueList(int o,int argc,const t_atom *argv) const { MsgBundle *m = MsgBundle::New(); m->Add(const_cast(this),o,argc,argv); FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueAnything(int o,const t_symbol *s,int argc,const t_atom *argv) const { MsgBundle *m = MsgBundle::New(); m->Add(const_cast(this),o,s,argc,argv); FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::MsgAddBang(MsgBundle *m,int n) const { m->Add(const_cast(this),n); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::MsgAddFloat(MsgBundle *m,int n,float f) const { m->Add(const_cast(this),n,f); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::MsgAddInt(MsgBundle *m,int n,int f) const { m->Add(const_cast(this),n,f); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::MsgAddSymbol(MsgBundle *m,int n,const t_symbol *s) const { m->Add(const_cast(this),n,s); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::MsgAddAtom(MsgBundle *m,int n,const t_atom &at) const { m->Add(const_cast(this),n,at); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::MsgAddList(MsgBundle *m,int n,int argc,const t_atom *argv) const { m->Add(const_cast(this),n,argc,argv); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::MsgAddAnything(MsgBundle *m,int n,const t_symbol *s,int argc,const t_atom *argv) const { m->Add(const_cast(this),n,s,argc,argv); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::SysForward(const t_symbol *recv,const t_symbol *s,int argc,const t_atom *argv) { void *cl = recv->s_thing; if(UNLIKELY(!cl)) return false; #if FLEXT_SYS == FLEXT_SYS_PD pd_typedmess((t_class **)cl,(t_symbol *)s,argc,(t_atom *)argv); #elif FLEXT_SYS == FLEXT_SYS_MAX typedmess(recv->s_thing,(t_symbol *)s,argc,(t_atom *)argv); #else # error Not implemented #endif return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::QueueForward(const t_symbol *recv,const t_symbol *s,int argc,const t_atom *argv) { MsgBundle *m = MsgBundle::New(); m->Add(recv,s,argc,argv); // send over queue FLEXT_TEMPINST(QVars)::queue->Push(m); return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::MsgForward(MsgBundle *m,const t_symbol *recv,const t_symbol *s,int argc,const t_atom *argv) { m->Add(recv,s,argc,argv); return true; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddIdle() { MsgBundle *m = MsgBundle::New(); m->Idle(const_cast(this)); // send over queue FLEXT_TEMPINST(QVars)::queue->Push(m); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddIdle(bool (*idlefun)(int argc,const t_atom *argv),int argc,const t_atom *argv) { MsgBundle *m = MsgBundle::New(); m->Idle(idlefun,argc,argv); // send over queue FLEXT_TEMPINST(QVars)::queue->Push(m); } #include "flpopns.h" #endif // __FLEXT_QUEUE_CPP flext-0-6-3/source/flsimd.cpp000066400000000000000000001724571446466241400161550ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flsimd.cpp \brief flext SIMD support functions If FLEXT_USE_SIMD is defined at compilation, SIMD instructions are used wherever feasible. If used with MSVC++ 6 the "Processor Pack" must be installed. If FLEXT_USE_IPP is defined the Intel Performance Package is used. */ #ifndef __FLEXT_SIMD_CPP #define __FLEXT_SIMD_CPP #include "flext.h" #include #if FLEXT_OS == FLEXT_OS_WIN #include #endif #ifdef FLEXT_USE_IPP #include #endif #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER // include MSVC SIMD header files #include // MMX #include // SSE #include // SSE2 #include // 3DNow! #elif defined(__APPLE__) && defined(__VEC__) #ifdef __MWERKS__ #if FLEXT_OSAPI == FLEXT_OSAPI_MAC_MACH #include #include #else #include #endif #pragma altivec_model on #include #include #elif defined(__GNUC__) #include #include #endif #endif #endif // FLEXT_USE_SIMD #include "flpushns.h" FLEXT_TEMPLATE unsigned long setsimdcaps(); /*! \brief Holds SIMD capability flags \internal */ FLEXT_TEMPIMPL(unsigned long FLEXT_CLASSDEF(flext))::simdcaps = FLEXT_TEMPINST(setsimdcaps)(); FLEXT_TEMPIMPL(unsigned long FLEXT_CLASSDEF(flext))::GetSIMDCapabilities() { return simdcaps; } #ifdef FLEXT_USE_SIMD #if FLEXT_CPU == FLEXT_CPU_IA32 || FLEXT_CPU == FLEXT_CPU_X86_64 #define _CPU_FEATURE_MMX 0x0001 #define _CPU_FEATURE_SSE 0x0002 #define _CPU_FEATURE_SSE2 0x0004 #define _CPU_FEATURE_3DNOW 0x0008 typedef struct _processor_info { int family; // family of the processor // e.g. 6 = Pentium-Pro architecture int model; // model of processor // e.g. 1 = Pentium-Pro for family = 6 int stepping; // processor revision number int feature; // processor feature // (same as return value from _cpuid) int os_support; // does OS Support the feature? int checks; // mask of checked bits in feature // and os_support fields } _p_info; // These are the bit flags that get set on calling cpuid // with register eax set to 1 #define _MMX_FEATURE_BIT 0x00800000 #define _SSE_FEATURE_BIT 0x02000000 #define _SSE2_FEATURE_BIT 0x04000000 // This bit is set when cpuid is called with // register set to 80000001h (only applicable to AMD) #define _3DNOW_FEATURE_BIT 0x80000000 #ifdef _MSC_VER inline int IsCPUID() { __try { _asm { xor eax, eax cpuid } } __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } return 1; } inline int _os_support(int feature) { __try { switch (feature) { case _CPU_FEATURE_SSE: __asm { xorps xmm0, xmm0 // executing SSE instruction } break; case _CPU_FEATURE_SSE2: __asm { xorpd xmm0, xmm0 // executing SSE2 instruction } break; case _CPU_FEATURE_3DNOW: __asm { pfrcp mm0, mm0 // executing 3DNow! instruction emms } break; case _CPU_FEATURE_MMX: __asm { pxor mm0, mm0 // executing MMX instruction emms } break; } } __except (EXCEPTION_EXECUTE_HANDLER) { if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) { return 0; } return 0; } return 1; } inline int _cpuid (_p_info *pinfo) { DWORD dwStandard = 0; DWORD dwFeature = 0; DWORD dwMax = 0; DWORD dwExt = 0; int feature = 0; int os_support = 0; union { struct { DWORD dw0; DWORD dw1; DWORD dw2; } s; } Ident; if (!IsCPUID()) { return 0; } _asm { push ebx push ecx push edx // get the vendor string xor eax, eax cpuid mov dwMax, eax mov Ident.s.dw0, ebx mov Ident.s.dw1, edx mov Ident.s.dw2, ecx // get the Standard bits mov eax, 1 cpuid mov dwStandard, eax mov dwFeature, edx // get AMD-specials mov eax, 80000000h cpuid cmp eax, 80000000h jc notamd mov eax, 80000001h cpuid mov dwExt, edx notamd: pop ecx pop ebx pop edx } if (dwFeature & _MMX_FEATURE_BIT) { feature |= _CPU_FEATURE_MMX; if (_os_support(_CPU_FEATURE_MMX)) os_support |= _CPU_FEATURE_MMX; } if (dwExt & _3DNOW_FEATURE_BIT) { feature |= _CPU_FEATURE_3DNOW; if (_os_support(_CPU_FEATURE_3DNOW)) os_support |= _CPU_FEATURE_3DNOW; } if (dwFeature & _SSE_FEATURE_BIT) { feature |= _CPU_FEATURE_SSE; if (_os_support(_CPU_FEATURE_SSE)) os_support |= _CPU_FEATURE_SSE; } if (dwFeature & _SSE2_FEATURE_BIT) { feature |= _CPU_FEATURE_SSE2; if (_os_support(_CPU_FEATURE_SSE2)) os_support |= _CPU_FEATURE_SSE2; } if (pinfo) { memset(pinfo, 0, sizeof(_p_info)); pinfo->os_support = os_support; pinfo->feature = feature; pinfo->family = (dwStandard >> 8) & 0xF; // retrieve family if (pinfo->family == 15) { // retrieve extended family pinfo->family |= (dwStandard >> 16) & 0xFF0; } pinfo->model = (dwStandard >> 4) & 0xF; // retrieve model if (pinfo->model == 15) { // retrieve extended model pinfo->model |= (dwStandard >> 12) & 0xF; } pinfo->stepping = (dwStandard) & 0xF; // retrieve stepping pinfo->checks = _CPU_FEATURE_MMX | _CPU_FEATURE_SSE | _CPU_FEATURE_SSE2 | _CPU_FEATURE_3DNOW; } return feature; } inline bool IsVectorAligned(const void *where) { return (reinterpret_cast(where)&(__alignof(__m128)-1)) == 0; } inline bool VectorsAligned(const void *v1,const void *v2) { return ( (reinterpret_cast(v1)|reinterpret_cast(v2)) &(__alignof(__m128)-1) ) == 0; } inline bool VectorsAligned(const void *v1,const void *v2,const void *v3) { return ( (reinterpret_cast(v1)|reinterpret_cast(v2)|reinterpret_cast(v3)) &(__alignof(__m128)-1) ) == 0; } inline bool VectorsAligned(const void *v1,const void *v2,const void *v3,const void *v4) { return ( (reinterpret_cast(v1)|reinterpret_cast(v2)|reinterpret_cast(v3)|reinterpret_cast(v4)) &(__alignof(__m128)-1) ) == 0; } #else // not MSVC inline int _cpuid (_p_info *pinfo) { if(pinfo) memset(pinfo,0,sizeof *pinfo); return 0; } #endif #endif /*! \brief Determine SIMD capabilities \internal */ inline unsigned long setsimdcaps() { unsigned long simdflags = flext::simd_none; #if FLEXT_CPU == FLEXT_CPU_IA32 || FLEXT_CPU == FLEXT_CPU_X86_64 _p_info cpuinfo; _cpuid(&cpuinfo); if(cpuinfo.os_support&_CPU_FEATURE_MMX) simdflags += flext::simd_mmx; if(cpuinfo.os_support&_CPU_FEATURE_3DNOW) simdflags += flext::simd_3dnow; if(cpuinfo.os_support&_CPU_FEATURE_SSE) simdflags += flext::simd_sse; if(cpuinfo.os_support&_CPU_FEATURE_SSE2) simdflags += flext::simd_sse2; #elif defined(__APPLE__) && defined(__VEC__) #if FLEXT_OSAPI == FLEXT_OSAPI_MAC_MACH int selectors[2] = { CTL_HW, HW_VECTORUNIT }; int hasVectorUnit = 0; size_t length = sizeof(hasVectorUnit); int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); if(!error && hasVectorUnit != 0) simdflags += flext::simd_altivec; #else long cpuAttributes; Boolean hasAltiVec = false; OSErr err = Gestalt( gestaltPowerPCProcessorFeatures, &cpuAttributes ); if( noErr == err ) if(( 1 << gestaltPowerPCHasVectorInstructions) & cpuAttributes) simdflags += flext::simd_altivec; #endif #endif return simdflags; } #if (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) /* functions for misaligned vector data - taken from the Altivec tutorial of Ian Ollmann, Ph.D. */ //! Load a vector from an unaligned location in memory inline vector unsigned char LoadUnaligned( vector unsigned char *v ) { vector unsigned char permuteVector = vec_lvsl( 0, (int*) v ); vector unsigned char low = vec_ld( 0, v ); vector unsigned char high = vec_ld( 15, v ); return vec_perm( low, high, permuteVector ); } /* //! Store a vector to an unaligned location in memory inline void StoreUnaligned( vector unsigned char v, vector unsigned char *where) { // Load the surrounding area vector unsigned char low = vec_ld( 0, where ); vector unsigned char high = vec_ld( 16, where ); // Prepare the constants that we need vector unsigned char permuteVector = vec_lvsr( 0, (int*) where ); vector unsigned char oxFF = (vector unsigned char)vec_splat_s8( -1 ); vector unsigned char ox00 = (vector unsigned char)vec_splat_s8( 0 ); // Make a mask for which parts of the vectors to swap out vector unsigned char mask = vec_perm( ox00, oxFF, permuteVector ); // Right rotate our input data v = vec_perm( v, v, permuteVector ); // Insert our data into the low and high vectors low = vec_sel( v, low, mask ); high = vec_sel( high, v, mask ); // Store the two aligned result vectors vec_st( low, 0, where ); vec_st( high, 16, where ); } */ inline vector float LoadUnaligned(const float *v ) { return (vector float)LoadUnaligned((vector unsigned char *)v); } /* inline void StoreUnaligned( vector float v,float *where) { return StoreUnaligned((vector unsigned char)v,(vector unsigned char *)where); } */ inline bool IsVectorAligned(const void *where) { return (reinterpret_cast(where)&(sizeof(vector float)-1)) == 0; } inline bool VectorsAligned(const void *v1,const void *v2) { return ( (reinterpret_cast(v1)|reinterpret_cast(v2)) &(sizeof(vector float)-1) ) == 0; } inline bool VectorsAligned(const void *v1,const void *v2,const void *v3) { return ( (reinterpret_cast(v1)|reinterpret_cast(v2)|reinterpret_cast(v3)) &(sizeof(vector float)-1) ) == 0; } inline bool VectorsAligned(const void *v1,const void *v2,const void *v3,const void *v4) { return ( (reinterpret_cast(v1)|reinterpret_cast(v2)|reinterpret_cast(v3)|reinterpret_cast(v4)) &(sizeof(vector float)-1) ) == 0; } inline vector float LoadValue(const float &f) { return vec_splat(IsVectorAligned(&f)?vec_ld(0,(vector float *)&f):LoadUnaligned(&f),0); } #endif #else // FLEXT_USE_SIMD inline unsigned long setsimdcaps() { return 0; } #endif // FLEXT_USE_SIMD FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::CopySamples(t_sample *dst,const t_sample *src,int cnt) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) ippsCopy_32f((const float *)src,(float *)dst,cnt); else if(sizeof(t_sample) == 8) ippsCopy_64f((const double *)src,(double *)dst,cnt); else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // single precision int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; __asm { mov eax,dword ptr [src] prefetcht0 [eax+0] prefetcht0 [eax+32] } if(IsVectorAligned(src)) { if(IsVectorAligned(dst)) { // aligned src, aligned dst __asm { mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ecx,[n] loopaa: prefetcht0 [eax+64] prefetcht0 [eax+96] movaps xmm0,xmmword ptr[eax] movaps xmmword ptr[edx],xmm0 movaps xmm1,xmmword ptr[eax+4*4] movaps xmmword ptr[edx+4*4],xmm1 movaps xmm2,xmmword ptr[eax+8*4] movaps xmmword ptr[edx+8*4],xmm2 movaps xmm3,xmmword ptr[eax+12*4] movaps xmmword ptr[edx+12*4],xmm3 add eax,16*4 add edx,16*4 loop loopaa } } else { // aligned src, unaligned dst __asm { mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ecx,[n] loopau: prefetcht0 [eax+64] prefetcht0 [eax+96] movaps xmm0,xmmword ptr[eax] movups xmmword ptr[edx],xmm0 movaps xmm1,xmmword ptr[eax+4*4] movups xmmword ptr[edx+4*4],xmm1 movaps xmm2,xmmword ptr[eax+8*4] movups xmmword ptr[edx+8*4],xmm2 movaps xmm3,xmmword ptr[eax+12*4] movups xmmword ptr[edx+12*4],xmm3 add eax,16*4 add edx,16*4 loop loopau } } } else { if(IsVectorAligned(dst)) { // unaligned src, aligned dst __asm { mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ecx,[n] loopua: prefetcht0 [eax+64] prefetcht0 [eax+96] movups xmm0,xmmword ptr[eax] movaps xmmword ptr[edx],xmm0 movups xmm1,xmmword ptr[eax+4*4] movaps xmmword ptr[edx+4*4],xmm1 movups xmm2,xmmword ptr[eax+8*4] movaps xmmword ptr[edx+8*4],xmm2 movups xmm3,xmmword ptr[eax+12*4] movaps xmmword ptr[edx+12*4],xmm3 add eax,16*4 add edx,16*4 loop loopua } } else { // unaligned src, unaligned dst __asm { mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ecx,[n] loopuu: prefetcht0 [eax+64] prefetcht0 [eax+96] movups xmm0,xmmword ptr[eax] movups xmmword ptr[edx],xmm0 movups xmm1,xmmword ptr[eax+4*4] movups xmmword ptr[edx+4*4],xmm1 movups xmm2,xmmword ptr[eax+8*4] movups xmmword ptr[edx+8*4],xmm2 movups xmm3,xmmword ptr[eax+12*4] movups xmmword ptr[edx+12*4],xmm3 add eax,16*4 add edx,16*4 loop loopuu } } } src += n<<4,dst += n<<4; zero: while(cnt--) *(dst++) = *(src++); } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VECTOROPS__) if(true) { int n = cnt>>2,n4 = n<<2; vScopy(n4,(vector float *)src,(vector float *)dst); cnt -= n4,src += n4,dst += n4; while(cnt--) *(dst++) = *(src++); } else #endif // _MSC_VER #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; while(n--) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; dst[4] = src[4]; dst[5] = src[5]; dst[6] = src[6]; dst[7] = src[7]; src += 8; dst += 8; } while(cnt--) *(dst++) = *(src++); } #endif } #if defined(FLEXT_USE_SIMD) && (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) // because of some frame code Altivec stuff should be in seperate functions.... FLEXT_TEMPLATE const vector float zero = (vector float)(0); FLEXT_TEMPLATE void SetAltivec(t_sample *dst,int cnt,t_sample s) { vector float svec = LoadValue(s); int n = cnt>>4; cnt -= n<<4; while(n--) { vec_st(svec,0,dst); vec_st(svec,16,dst); vec_st(svec,32,dst); vec_st(svec,48,dst); dst += 16; } while(cnt--) *(dst++) = s; } FLEXT_TEMPLATE void MulAltivec(t_sample *dst,const t_sample *src,t_sample op,int cnt) { const vector float arg = LoadValue(op); int n = cnt>>4; cnt -= n<<4; for(; n--; src += 16,dst += 16) { vector float a1 = vec_ld( 0,src); vector float a2 = vec_ld(16,src); vector float a3 = vec_ld(32,src); vector float a4 = vec_ld(48,src); a1 = vec_madd(a1,arg,zero); a2 = vec_madd(a2,arg,zero); a3 = vec_madd(a3,arg,zero); a4 = vec_madd(a4,arg,zero); vec_st(a1, 0,dst); vec_st(a2,16,dst); vec_st(a3,32,dst); vec_st(a4,48,dst); } while(cnt--) *(dst++) = *(src++)*op; } FLEXT_TEMPLATE void MulAltivec(t_sample *dst,const t_sample *src,const t_sample *op,int cnt) { int n = cnt>>4; cnt -= n<<4; for(; n--; src += 16,op += 16,dst += 16) { vector float a1 = vec_ld( 0,src),b1 = vec_ld( 0,op); vector float a2 = vec_ld(16,src),b2 = vec_ld(16,op); vector float a3 = vec_ld(32,src),b3 = vec_ld(32,op); vector float a4 = vec_ld(48,src),b4 = vec_ld(48,op); a1 = vec_madd(a1,b1,zero); a2 = vec_madd(a2,b2,zero); a3 = vec_madd(a3,b3,zero); a4 = vec_madd(a4,b4,zero); vec_st(a1, 0,dst); vec_st(a2,16,dst); vec_st(a3,32,dst); vec_st(a4,48,dst); } while(cnt--) *(dst++) = *(src++) * *(op++); } FLEXT_TEMPLATE void AddAltivec(t_sample *dst,const t_sample *src,t_sample op,int cnt) { const vector float arg = LoadValue(op); int n = cnt>>4; cnt -= n<<4; for(; n--; src += 16,dst += 16) { vector float a1 = vec_ld( 0,src); vector float a2 = vec_ld(16,src); vector float a3 = vec_ld(32,src); vector float a4 = vec_ld(48,src); a1 = vec_add(a1,arg); a2 = vec_add(a2,arg); a3 = vec_add(a3,arg); a4 = vec_add(a4,arg); vec_st(a1, 0,dst); vec_st(a2,16,dst); vec_st(a3,32,dst); vec_st(a4,48,dst); } while(cnt--) *(dst++) = *(src++)+op; } FLEXT_TEMPLATE void AddAltivec(t_sample *dst,const t_sample *src,const t_sample *op,int cnt) { int n = cnt>>4; cnt -= n<<4; for(; n--; src += 16,op += 16,dst += 16) { vector float a1 = vec_ld( 0,src),b1 = vec_ld( 0,op); vector float a2 = vec_ld(16,src),b2 = vec_ld(16,op); vector float a3 = vec_ld(32,src),b3 = vec_ld(32,op); vector float a4 = vec_ld(48,src),b4 = vec_ld(48,op); a1 = vec_add(a1,b1); a2 = vec_add(a2,b2); a3 = vec_add(a3,b3); a4 = vec_add(a4,b4); vec_st(a1, 0,dst); vec_st(a2,16,dst); vec_st(a3,32,dst); vec_st(a4,48,dst); } while(cnt--) *(dst++) = *(src++) + *(op++); } FLEXT_TEMPLATE void ScaleAltivec(t_sample *dst,const t_sample *src,t_sample opmul,t_sample opadd,int cnt) { const vector float argmul = LoadValue(opmul); const vector float argadd = LoadValue(opadd); int n = cnt>>4; cnt -= n<<4; for(; n--; src += 16,dst += 16) { vec_st(vec_madd(vec_ld( 0,src),argmul,argadd), 0,dst); vec_st(vec_madd(vec_ld(16,src),argmul,argadd),16,dst); vec_st(vec_madd(vec_ld(32,src),argmul,argadd),32,dst); vec_st(vec_madd(vec_ld(48,src),argmul,argadd),48,dst); } while(cnt--) *(dst++) = *(src++)*opmul+opadd; } FLEXT_TEMPLATE void ScaleAltivec(t_sample *dst,const t_sample *src,t_sample opmul,const t_sample *add,int cnt) { const vector float argmul = LoadValue(opmul); int n = cnt>>4; cnt -= n<<4; for(; n--; src += 16,dst += 16,add += 16) { vec_st(vec_madd(vec_ld( 0,src),argmul,vec_ld( 0,add)), 0,dst); vec_st(vec_madd(vec_ld(16,src),argmul,vec_ld(16,add)),16,dst); vec_st(vec_madd(vec_ld(32,src),argmul,vec_ld(32,add)),32,dst); vec_st(vec_madd(vec_ld(48,src),argmul,vec_ld(48,add)),48,dst); } while(cnt--) *(dst++) = *(src++) * opmul + *(add++); } FLEXT_TEMPLATE void ScaleAltivec(t_sample *dst,const t_sample *src,const t_sample *mul,const t_sample *add,int cnt) { int n = cnt>>4; cnt -= n<<4; for(; n--; src += 16,dst += 16,mul += 16,add += 16) { vec_st(vec_madd(vec_ld( 0,src),vec_ld( 0,mul),vec_ld( 0,add)), 0,dst); vec_st(vec_madd(vec_ld(16,src),vec_ld(16,mul),vec_ld(16,add)),16,dst); vec_st(vec_madd(vec_ld(32,src),vec_ld(32,mul),vec_ld(32,add)),32,dst); vec_st(vec_madd(vec_ld(48,src),vec_ld(48,mul),vec_ld(48,add)),48,dst); } while(cnt--) *(dst++) = *(src++) * *(mul++) + *(add++); } #endif FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::SetSamples(t_sample *dst,int cnt,t_sample s) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) ippsSet_32f((float)s,(float *)dst,cnt); else if(sizeof(t_sample) == 8) ippsSet_64f((double)s,(double *)dst,cnt); else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // single precision int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; __asm { movss xmm0,xmmword ptr [s] shufps xmm0,xmm0,0 } if(IsVectorAligned(dst)) { // aligned version __asm { mov ecx,[n] mov edx,dword ptr [dst] loopa: movaps xmmword ptr[edx],xmm0 movaps xmmword ptr[edx+4*4],xmm0 movaps xmmword ptr[edx+8*4],xmm0 movaps xmmword ptr[edx+12*4],xmm0 add edx,16*4 loop loopa } } else { // unaligned version __asm { mov ecx,[n] mov edx,dword ptr [dst] loopu: movups xmmword ptr[edx],xmm0 movups xmmword ptr[edx+4*4],xmm0 movups xmmword ptr[edx+8*4],xmm0 movups xmmword ptr[edx+12*4],xmm0 add edx,16*4 loop loopu } } dst += n<<4; zero: while(cnt--) *(dst++) = s; } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) if(GetSIMDCapabilities()&simd_altivec && IsVectorAligned(dst)) SetAltivec(dst,cnt,s); else #endif #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; while(n--) { dst[0] = dst[1] = dst[2] = dst[3] = dst[4] = dst[5] = dst[6] = dst[7] = s; dst += 8; } while(cnt--) *(dst++) = s; } #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::MulSamples(t_sample *dst,const t_sample *src,t_sample op,int cnt) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) { ippsMulC_32f((const float *)src,(float)op,(float *)dst,cnt); } else if(sizeof(t_sample) == 8) { ippsMulC_64f((const double *)src,(double)op,(double *)dst,cnt); } else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // single precision __m128 a = _mm_load1_ps(&op); int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; __asm { mov eax,dword ptr [src] prefetcht0 [eax+0] prefetcht0 [eax+32] movss xmm0,xmmword ptr [op] shufps xmm0,xmm0,0 } if(VectorsAligned(src,dst)) { // aligned version __asm { mov ecx,[n] mov eax,dword ptr [src] mov edx,dword ptr [dst] loopa: prefetcht0 [eax+64] prefetcht0 [eax+96] movaps xmm1,xmmword ptr[eax] mulps xmm1,xmm0 movaps xmmword ptr[edx],xmm1 movaps xmm2,xmmword ptr[eax+4*4] mulps xmm2,xmm0 movaps xmmword ptr[edx+4*4],xmm2 movaps xmm3,xmmword ptr[eax+8*4] mulps xmm3,xmm0 movaps xmmword ptr[edx+8*4],xmm3 movaps xmm4,xmmword ptr[eax+12*4] mulps xmm4,xmm0 movaps xmmword ptr[edx+12*4],xmm4 add eax,16*4 add edx,16*4 loop loopa } } else { // unaligned version __asm { mov ecx,[n] mov eax,dword ptr [src] mov edx,dword ptr [dst] loopu: prefetcht0 [eax+64] prefetcht0 [eax+96] movups xmm1,xmmword ptr[eax] mulps xmm1,xmm0 movups xmmword ptr[edx],xmm1 movups xmm2,xmmword ptr[eax+4*4] mulps xmm2,xmm0 movups xmmword ptr[edx+4*4],xmm2 movups xmm3,xmmword ptr[eax+8*4] mulps xmm3,xmm0 movups xmmword ptr[edx+8*4],xmm3 movups xmm4,xmmword ptr[eax+12*4] mulps xmm4,xmm0 movups xmmword ptr[edx+12*4],xmm4 add eax,16*4 add edx,16*4 loop loopu } } src += n<<4,dst += n<<4; zero: while(cnt--) *(dst++) = *(src++)*op; } else #elif defined(__APPLE__) && defined(__VDSP__) if(true) { vDSP_vsmul(src,1,&op,dst,1,cnt); } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) if(GetSIMDCapabilities()&simd_altivec && VectorsAligned(src,dst)) MulAltivec(dst,src,op,cnt); else #endif // _MSC_VER #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; if(src == dst) { while(n--) { dst[0] *= op; dst[1] *= op; dst[2] *= op; dst[3] *= op; dst[4] *= op; dst[5] *= op; dst[6] *= op; dst[7] *= op; dst += 8; } while(cnt--) *(dst++) *= op; } else { while(n--) { dst[0] = src[0]*op; dst[1] = src[1]*op; dst[2] = src[2]*op; dst[3] = src[3]*op; dst[4] = src[4]*op; dst[5] = src[5]*op; dst[6] = src[6]*op; dst[7] = src[7]*op; src += 8; dst += 8; } while(cnt--) *(dst++) = *(src++)*op; } } #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::MulSamples(t_sample *dst,const t_sample *src,const t_sample *op,int cnt) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) { ippsMul_32f((const float *)src,(const float *)op,(float *)dst,cnt); } else if(sizeof(t_sample) == 8) { ippsMul_32f((const double *)src,(const double *)op,(double *)dst,cnt); } else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // single precision int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; __asm { mov eax,[src] mov ebx,[op] prefetcht0 [eax+0] prefetcht0 [ebx+0] prefetcht0 [eax+32] prefetcht0 [ebx+32] } if(VectorsAligned(src,dst)) { if(IsVectorAligned(op)) { __asm { mov ecx,[n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [op] loopaa: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movaps xmm0,xmmword ptr[eax] movaps xmm1,xmmword ptr[ebx] mulps xmm0,xmm1 movaps xmmword ptr[edx],xmm0 movaps xmm2,xmmword ptr[eax+4*4] movaps xmm3,xmmword ptr[ebx+4*4] mulps xmm2,xmm3 movaps xmmword ptr[edx+4*4],xmm2 movaps xmm4,xmmword ptr[eax+8*4] movaps xmm5,xmmword ptr[ebx+8*4] mulps xmm4,xmm5 movaps xmmword ptr[edx+8*4],xmm4 movaps xmm6,xmmword ptr[eax+12*4] movaps xmm7,xmmword ptr[ebx+12*4] mulps xmm6,xmm7 movaps xmmword ptr[edx+12*4],xmm6 add eax,16*4 add ebx,16*4 add edx,16*4 loop loopaa } } else { __asm { mov ecx,[n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [op] loopau: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movaps xmm0,xmmword ptr[eax] movups xmm1,xmmword ptr[ebx] mulps xmm0,xmm1 movaps xmmword ptr[edx],xmm0 movaps xmm2,xmmword ptr[eax+4*4] movups xmm3,xmmword ptr[ebx+4*4] mulps xmm2,xmm3 movaps xmmword ptr[edx+4*4],xmm2 movaps xmm4,xmmword ptr[eax+8*4] movups xmm5,xmmword ptr[ebx+8*4] mulps xmm4,xmm5 movaps xmmword ptr[edx+8*4],xmm4 movaps xmm6,xmmword ptr[eax+12*4] movups xmm7,xmmword ptr[ebx+12*4] mulps xmm6,xmm7 movaps xmmword ptr[edx+12*4],xmm6 add eax,16*4 add ebx,16*4 add edx,16*4 loop loopau } } } else { if(IsVectorAligned(op)) { __asm { mov ecx,[n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [op] loopua: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movups xmm0,xmmword ptr[eax] movaps xmm1,xmmword ptr[ebx] mulps xmm0,xmm1 movups xmmword ptr[edx],xmm0 movups xmm2,xmmword ptr[eax+4*4] movaps xmm3,xmmword ptr[ebx+4*4] mulps xmm2,xmm3 movups xmmword ptr[edx+4*4],xmm2 movups xmm4,xmmword ptr[eax+8*4] movaps xmm5,xmmword ptr[ebx+8*4] mulps xmm4,xmm5 movups xmmword ptr[edx+8*4],xmm4 movups xmm6,xmmword ptr[eax+12*4] movaps xmm7,xmmword ptr[ebx+12*4] mulps xmm6,xmm7 movups xmmword ptr[edx+12*4],xmm6 add eax,16*4 add ebx,16*4 add edx,16*4 loop loopua } } else { __asm { mov ecx,[n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [op] loopuu: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movups xmm0,xmmword ptr[eax] movups xmm1,xmmword ptr[ebx] mulps xmm0,xmm1 movups xmmword ptr[edx],xmm0 movups xmm2,xmmword ptr[eax+4*4] movups xmm3,xmmword ptr[ebx+4*4] mulps xmm2,xmm3 movups xmmword ptr[edx+4*4],xmm2 movups xmm4,xmmword ptr[eax+8*4] movups xmm5,xmmword ptr[ebx+8*4] mulps xmm4,xmm5 movups xmmword ptr[edx+8*4],xmm4 movups xmm6,xmmword ptr[eax+12*4] movups xmm7,xmmword ptr[ebx+12*4] mulps xmm6,xmm7 movups xmmword ptr[edx+12*4],xmm6 add eax,16*4 add ebx,16*4 add edx,16*4 loop loopuu } } } src += n<<4,dst += n<<4,op += n<<4; zero: while(cnt--) *(dst++) = *(src++) * *(op++); } else #elif defined(__APPLE__) && defined(__VDSP__) if(true) { vDSP_vmul(src,1,op,1,dst,1,cnt); } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) if(GetSIMDCapabilities()&simd_altivec && VectorsAligned(src,op,dst)) MulAltivec(dst,src,op,cnt); else #endif // _MSC_VER #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; if(src == dst) { while(n--) { dst[0] *= op[0]; dst[1] *= op[1]; dst[2] *= op[2]; dst[3] *= op[3]; dst[4] *= op[4]; dst[5] *= op[5]; dst[6] *= op[6]; dst[7] *= op[7]; dst += 8; op += 8; } while(cnt--) *(dst++) *= *(op++); } else { while(n--) { dst[0] = src[0]*op[0]; dst[1] = src[1]*op[1]; dst[2] = src[2]*op[2]; dst[3] = src[3]*op[3]; dst[4] = src[4]*op[4]; dst[5] = src[5]*op[5]; dst[6] = src[6]*op[6]; dst[7] = src[7]*op[7]; src += 8; dst += 8; op += 8; } while(cnt--) *(dst++) = *(src++) * *(op++); } } #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::AddSamples(t_sample *dst,const t_sample *src,t_sample op,int cnt) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) { ippsAddC_32f((const float *)src,(float)op,(float *)dst,cnt); } else if(sizeof(t_sample) == 8) { ippsAddC_64f_I((const double *)src,(double)op,(double *)dst,cnt); } else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // single precision int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; __asm { mov eax,[src] prefetcht0 [eax+0] prefetcht0 [eax+32] movss xmm0,xmmword ptr [op] shufps xmm0,xmm0,0 } if(VectorsAligned(src,dst)) { // aligned version __asm { mov ecx,[n] mov eax,dword ptr [src] mov edx,dword ptr [dst] loopa: prefetcht0 [eax+64] prefetcht0 [eax+96] movaps xmm1,xmmword ptr[eax] addps xmm1,xmm0 movaps xmmword ptr[edx],xmm1 movaps xmm2,xmmword ptr[eax+4*4] addps xmm2,xmm0 movaps xmmword ptr[edx+4*4],xmm2 movaps xmm3,xmmword ptr[eax+8*4] addps xmm3,xmm0 movaps xmmword ptr[edx+8*4],xmm3 movaps xmm4,xmmword ptr[eax+12*4] addps xmm4,xmm0 movaps xmmword ptr[edx+12*4],xmm4 add eax,16*4 add edx,16*4 loop loopa } } else { // unaligned version __asm { mov ecx,[n] mov eax,dword ptr [src] mov edx,dword ptr [dst] loopu: prefetcht0 [eax+64] prefetcht0 [eax+96] movups xmm1,xmmword ptr[eax] addps xmm1,xmm0 movups xmmword ptr[edx],xmm1 movups xmm2,xmmword ptr[eax+4*4] addps xmm2,xmm0 movups xmmword ptr[edx+4*4],xmm2 movups xmm3,xmmword ptr[eax+8*4] addps xmm3,xmm0 movups xmmword ptr[edx+8*4],xmm3 movups xmm4,xmmword ptr[eax+12*4] addps xmm4,xmm0 movups xmmword ptr[edx+12*4],xmm4 add eax,16*4 add edx,16*4 loop loopu } } src += n<<4,dst += n<<4,op += n<<4; zero: while(cnt--) *(dst++) = *(src++)+op; } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) if(GetSIMDCapabilities()&simd_altivec && VectorsAligned(src,dst)) AddAltivec(dst,src,op,cnt); else #endif // _MSC_VER #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; if(src == dst) { while(n--) { dst[0] += op; dst[1] += op; dst[2] += op; dst[3] += op; dst[4] += op; dst[5] += op; dst[6] += op; dst[7] += op; dst += 8; } while(cnt--) *(dst++) += op; } else { while(n--) { dst[0] = src[0]+op; dst[1] = src[1]+op; dst[2] = src[2]+op; dst[3] = src[3]+op; dst[4] = src[4]+op; dst[5] = src[5]+op; dst[6] = src[6]+op; dst[7] = src[7]+op; src += 8; dst += 8; } while(cnt--) *(dst++) = *(src++)+op; } } #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::AddSamples(t_sample *dst,const t_sample *src,const t_sample *op,int cnt) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) { ippsAdd_32f((const float *)src,(const float *)op,(float *)dst,cnt); } else if(sizeof(t_sample) == 8) { ippsAdd_64f((const double *)src,(const double *)op,(double *)dst,cnt); } else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // Prefetch cache __asm { mov eax,dword ptr [src] mov ebx,dword ptr [op] prefetcht0 [eax] prefetcht0 [ebx] prefetcht0 [eax+32] prefetcht0 [ebx+32] } // single precision int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; if(VectorsAligned(src,dst)) { if(IsVectorAligned(op)) { __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [op] loopaa: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movaps xmm0,xmmword ptr[eax] movaps xmm1,xmmword ptr[ebx] addps xmm0,xmm1 movaps xmmword ptr[edx],xmm0 movaps xmm2,xmmword ptr[eax+4*4] movaps xmm3,xmmword ptr[ebx+4*4] addps xmm2,xmm3 movaps xmmword ptr[edx+4*4],xmm2 movaps xmm4,xmmword ptr[eax+8*4] movaps xmm5,xmmword ptr[ebx+8*4] addps xmm4,xmm5 movaps xmmword ptr[edx+8*4],xmm4 movaps xmm6,xmmword ptr[eax+12*4] movaps xmm7,xmmword ptr[ebx+12*4] addps xmm6,xmm7 movaps xmmword ptr[edx+12*4],xmm6 add eax,16*4 add ebx,16*4 add edx,16*4 loop loopaa } } else { __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [op] loopau: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movaps xmm0,xmmword ptr[eax] movups xmm1,xmmword ptr[ebx] addps xmm0,xmm1 movaps xmmword ptr[edx],xmm0 movaps xmm2,xmmword ptr[eax+4*4] movups xmm3,xmmword ptr[ebx+4*4] addps xmm2,xmm3 movaps xmmword ptr[edx+4*4],xmm2 movaps xmm4,xmmword ptr[eax+8*4] movups xmm5,xmmword ptr[ebx+8*4] addps xmm4,xmm5 movaps xmmword ptr[edx+8*4],xmm4 movaps xmm6,xmmword ptr[eax+12*4] movups xmm7,xmmword ptr[ebx+12*4] addps xmm6,xmm7 movaps xmmword ptr[edx+12*4],xmm6 add eax,16*4 add ebx,16*4 add edx,16*4 loop loopau } } } else { if(IsVectorAligned(op)) { __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [op] loopua: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movups xmm0,xmmword ptr[eax] movaps xmm1,xmmword ptr[ebx] addps xmm0,xmm1 movups xmmword ptr[edx],xmm0 movups xmm2,xmmword ptr[eax+4*4] movaps xmm3,xmmword ptr[ebx+4*4] addps xmm2,xmm3 movups xmmword ptr[edx+4*4],xmm2 movups xmm4,xmmword ptr[eax+8*4] movaps xmm5,xmmword ptr[ebx+8*4] addps xmm4,xmm5 movups xmmword ptr[edx+8*4],xmm4 movups xmm6,xmmword ptr[eax+12*4] movaps xmm7,xmmword ptr[ebx+12*4] addps xmm6,xmm7 movups xmmword ptr[edx+12*4],xmm6 add eax,16*4 add ebx,16*4 add edx,16*4 loop loopua } } else { __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [op] loopuu: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movups xmm0,xmmword ptr[eax] movups xmm1,xmmword ptr[ebx] addps xmm0,xmm1 movups xmmword ptr[edx],xmm0 movups xmm2,xmmword ptr[eax+4*4] movups xmm3,xmmword ptr[ebx+4*4] addps xmm2,xmm3 movups xmmword ptr[edx+4*4],xmm2 movups xmm4,xmmword ptr[eax+8*4] movups xmm5,xmmword ptr[ebx+8*4] addps xmm4,xmm5 movups xmmword ptr[edx+8*4],xmm4 movups xmm6,xmmword ptr[eax+12*4] movups xmm7,xmmword ptr[ebx+12*4] addps xmm6,xmm7 movups xmmword ptr[edx+12*4],xmm6 add eax,16*4 add ebx,16*4 add edx,16*4 loop loopuu } } } src += n<<4,dst += n<<4,op += n<<4; zero: while(cnt--) *(dst++) = *(src++) + *(op++); } else #elif defined(__APPLE__) && defined(__VDSP__) if(true) { vDSP_vadd(src,1,op,1,dst,1,cnt); } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) if(GetSIMDCapabilities()&simd_altivec && VectorsAligned(src,op,dst)) AddAltivec(dst,src,op,cnt); else #endif // _MSC_VER #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; if(dst == src) { while(n--) { dst[0] += op[0]; dst[1] += op[1]; dst[2] += op[2]; dst[3] += op[3]; dst[4] += op[4]; dst[5] += op[5]; dst[6] += op[6]; dst[7] += op[7]; dst += 8; op += 8; } while(cnt--) *(dst++) += *(op++); } else { while(n--) { dst[0] = src[0]+op[0]; dst[1] = src[1]+op[1]; dst[2] = src[2]+op[2]; dst[3] = src[3]+op[3]; dst[4] = src[4]+op[4]; dst[5] = src[5]+op[5]; dst[6] = src[6]+op[6]; dst[7] = src[7]+op[7]; src += 8; dst += 8; op += 8; } while(cnt--) *(dst++) = *(src++) + *(op++); } } #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ScaleSamples(t_sample *dst,const t_sample *src,t_sample opmul,t_sample opadd,int cnt) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) { ippsMulC_32f((const float *)src,(float)opmul,(float *)dst,cnt); ippsAddC_32f_I((float)opadd,(float *)dst,cnt); } else if(sizeof(t_sample) == 8) { ippsMulC_64f((const double *)src,(double)opmul,(double *)dst,cnt); ippsAddC_64f_I((double)opadd,(double *)dst,cnt); } else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // single precision int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; __asm { mov eax,dword ptr [src] prefetcht0 [eax+0] prefetcht0 [eax+32] movss xmm0,xmmword ptr [opadd] shufps xmm0,xmm0,0 movss xmm1,xmmword ptr [opmul] shufps xmm1,xmm1,0 } if(VectorsAligned(src,dst)) { // aligned version __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] loopa: prefetcht0 [eax+64] prefetcht0 [eax+96] movaps xmm2,xmmword ptr[eax] mulps xmm2,xmm1 addps xmm2,xmm0 movaps xmmword ptr[edx],xmm2 movaps xmm3,xmmword ptr[eax+4*4] mulps xmm3,xmm1 addps xmm3,xmm0 movaps xmmword ptr[edx+4*4],xmm3 movaps xmm4,xmmword ptr[eax+8*4] mulps xmm4,xmm1 addps xmm4,xmm0 movaps xmmword ptr[edx+8*4],xmm4 movaps xmm5,xmmword ptr[eax+12*4] mulps xmm5,xmm1 addps xmm5,xmm0 movaps xmmword ptr[edx+12*4],xmm5 add eax,16*4 add edx,16*4 loop loopa } } else { // unaligned version __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] loopu: prefetcht0 [eax+64] prefetcht0 [eax+96] movups xmm2,xmmword ptr[eax] mulps xmm2,xmm1 addps xmm2,xmm0 movups xmmword ptr[edx],xmm2 movups xmm3,xmmword ptr[eax+4*4] mulps xmm3,xmm1 addps xmm3,xmm0 movups xmmword ptr[edx+4*4],xmm3 movups xmm4,xmmword ptr[eax+8*4] mulps xmm4,xmm1 addps xmm4,xmm0 movups xmmword ptr[edx+8*4],xmm4 movups xmm5,xmmword ptr[eax+12*4] mulps xmm5,xmm1 addps xmm5,xmm0 movups xmmword ptr[edx+12*4],xmm5 add eax,16*4 add edx,16*4 loop loopu } } src += n<<4,dst += n<<4; zero: while(cnt--) *(dst++) = *(src++)*opmul+opadd; } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) if(GetSIMDCapabilities()&simd_altivec && VectorsAligned(src,dst)) ScaleAltivec(dst,src,opmul,opadd,cnt); else #endif // _MSC_VER #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; while(n--) { dst[0] = src[0]*opmul+opadd; dst[1] = src[1]*opmul+opadd; dst[2] = src[2]*opmul+opadd; dst[3] = src[3]*opmul+opadd; dst[4] = src[4]*opmul+opadd; dst[5] = src[5]*opmul+opadd; dst[6] = src[6]*opmul+opadd; dst[7] = src[7]*opmul+opadd; src += 8; dst += 8; } while(cnt--) *(dst++) = *(src++)*opmul+opadd; } #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ScaleSamples(t_sample *dst,const t_sample *src,t_sample opmul,const t_sample *opadd,int cnt) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) { ippsMulC_32f((const float *)src,(float)opmul,(float *)dst,cnt); ippsAdd_32f_I((float *)opadd,(float *)dst,cnt); } else if(sizeof(t_sample) == 8) { ippsMulC_64f((const double *)src,(double)opmul,(double *)dst,cnt); ippsAdd_64f_I((double *)opadd,(double *)dst,cnt); } else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // single precision int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; __asm { mov eax,dword ptr [src] prefetcht0 [eax+0] prefetcht0 [eax+32] movss xmm0,xmmword ptr [opmul] shufps xmm0,xmm0,0 } if(VectorsAligned(src,dst,opadd)) { // aligned version __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [opadd] loopa: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movaps xmm2,xmmword ptr[eax] movaps xmm1,xmmword ptr[ebx] mulps xmm2,xmm0 addps xmm2,xmm1 movaps xmmword ptr[edx],xmm2 movaps xmm3,xmmword ptr[eax+4*4] movaps xmm1,xmmword ptr[ebx+4*4] mulps xmm3,xmm0 addps xmm3,xmm1 movaps xmmword ptr[edx+4*4],xmm3 movaps xmm4,xmmword ptr[eax+8*4] movaps xmm1,xmmword ptr[ebx+8*4] mulps xmm4,xmm0 addps xmm4,xmm1 movaps xmmword ptr[edx+8*4],xmm4 movaps xmm5,xmmword ptr[eax+12*4] movaps xmm1,xmmword ptr[ebx+12*4] mulps xmm5,xmm0 addps xmm5,xmm1 movaps xmmword ptr[edx+12*4],xmm5 add eax,16*4 add edx,16*4 add ebx,16*4 loop loopa } } else { // unaligned version __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov ebx,dword ptr [opadd] loopu: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] movups xmm2,xmmword ptr[eax] movups xmm1,xmmword ptr[ebx] mulps xmm2,xmm0 addps xmm2,xmm1 movups xmmword ptr[edx],xmm2 movups xmm3,xmmword ptr[eax+4*4] movups xmm1,xmmword ptr[ebx+4*4] mulps xmm3,xmm0 addps xmm3,xmm1 movups xmmword ptr[edx+4*4],xmm3 movups xmm4,xmmword ptr[eax+8*4] movups xmm1,xmmword ptr[ebx+8*4] mulps xmm4,xmm0 addps xmm4,xmm1 movups xmmword ptr[edx+8*4],xmm4 movups xmm5,xmmword ptr[eax+12*4] movups xmm1,xmmword ptr[ebx+12*4] mulps xmm5,xmm0 addps xmm5,xmm1 movups xmmword ptr[edx+12*4],xmm5 add eax,16*4 add edx,16*4 add ebx,16*4 loop loopu } } src += n<<4,dst += n<<4,opadd += n<<4; zero: while(cnt--) *(dst++) = *(src++) * opmul + *(opadd++); } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) if(GetSIMDCapabilities()&simd_altivec && VectorsAligned(src,dst,opadd)) ScaleAltivec(dst,src,opmul,opadd,cnt); else #endif // _MSC_VER #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; if(dst == opadd) { while(n--) { dst[0] += src[0]*opmul; dst[1] += src[1]*opmul; dst[2] += src[2]*opmul; dst[3] += src[3]*opmul; dst[4] += src[4]*opmul; dst[5] += src[5]*opmul; dst[6] += src[6]*opmul; dst[7] += src[7]*opmul; src += 8; dst += 8; } while(cnt--) *(dst++) += *(src++)*opmul; } else { while(n--) { dst[0] = src[0]*opmul+opadd[0]; dst[1] = src[1]*opmul+opadd[1]; dst[2] = src[2]*opmul+opadd[2]; dst[3] = src[3]*opmul+opadd[3]; dst[4] = src[4]*opmul+opadd[4]; dst[5] = src[5]*opmul+opadd[5]; dst[6] = src[6]*opmul+opadd[6]; dst[7] = src[7]*opmul+opadd[7]; src += 8; dst += 8; opadd += 8; } while(cnt--) *(dst++) = *(src++)*opmul+*(opadd++); } } #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ScaleSamples(t_sample *dst,const t_sample *src,const t_sample *opmul,const t_sample *opadd,int cnt) { #ifdef FLEXT_USE_IPP if(sizeof(t_sample) == 4) { ippsMul_32f((const float *)src,(const float *)opmul,(float *)dst,cnt); ippsAdd_32f_I((const float *)opadd,(float *)dst,cnt); } else if(sizeof(t_sample) == 8) { ippsMul_64f((const double *)src,(const double *)opmul,(double *)dst,cnt); ippsAdd_64f_I((const double *)opadd,(double *)dst,cnt); } else ERRINTERNAL(); #else #ifdef FLEXT_USE_SIMD #ifdef _MSC_VER if(GetSIMDCapabilities()&simd_sse) { // single precision int n = cnt>>4; if(!n) goto zero; cnt -= n<<4; __asm { mov eax,dword ptr [src] prefetcht0 [eax+0] prefetcht0 [eax+32] } if(VectorsAligned(src,dst,opmul,opadd)) { // aligned version __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov esi,dword ptr [opmul] mov ebx,dword ptr [opadd] loopa: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [esi+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] prefetcht0 [esi+96] movaps xmm2,xmmword ptr[eax] movaps xmm0,xmmword ptr[esi] movaps xmm1,xmmword ptr[ebx] mulps xmm2,xmm0 addps xmm2,xmm1 movaps xmmword ptr[edx],xmm2 movaps xmm3,xmmword ptr[eax+4*4] movaps xmm0,xmmword ptr[esi+4*4] movaps xmm1,xmmword ptr[ebx+4*4] mulps xmm3,xmm0 addps xmm3,xmm1 movaps xmmword ptr[edx+4*4],xmm3 movaps xmm4,xmmword ptr[eax+8*4] movaps xmm0,xmmword ptr[esi+8*4] movaps xmm1,xmmword ptr[ebx+8*4] mulps xmm4,xmm0 addps xmm4,xmm1 movaps xmmword ptr[edx+8*4],xmm4 movaps xmm5,xmmword ptr[eax+12*4] movaps xmm0,xmmword ptr[esi+12*4] movaps xmm1,xmmword ptr[ebx+12*4] mulps xmm5,xmm0 addps xmm5,xmm1 movaps xmmword ptr[edx+12*4],xmm5 add eax,16*4 add edx,16*4 add ebx,16*4 add esi,16*4 loop loopa } } else { // unaligned version __asm { mov ecx,dword ptr [n] mov eax,dword ptr [src] mov edx,dword ptr [dst] mov esi,dword ptr [opmul] mov ebx,dword ptr [opadd] loopu: prefetcht0 [eax+64] prefetcht0 [ebx+64] prefetcht0 [esi+64] prefetcht0 [eax+96] prefetcht0 [ebx+96] prefetcht0 [esi+96] movups xmm2,xmmword ptr[eax] movups xmm0,xmmword ptr[esi] movups xmm1,xmmword ptr[ebx] mulps xmm2,xmm0 addps xmm2,xmm1 movups xmmword ptr[edx],xmm2 movups xmm3,xmmword ptr[eax+4*4] movups xmm0,xmmword ptr[esi+4*4] movups xmm1,xmmword ptr[ebx+4*4] mulps xmm3,xmm0 addps xmm3,xmm1 movups xmmword ptr[edx+4*4],xmm3 movups xmm4,xmmword ptr[eax+8*4] movups xmm0,xmmword ptr[esi+8*4] movups xmm1,xmmword ptr[ebx+8*4] mulps xmm4,xmm0 addps xmm4,xmm1 movups xmmword ptr[edx+8*4],xmm4 movups xmm5,xmmword ptr[eax+12*4] movups xmm0,xmmword ptr[esi+12*4] movups xmm1,xmmword ptr[ebx+12*4] mulps xmm5,xmm0 addps xmm5,xmm1 movups xmmword ptr[edx+12*4],xmm5 add eax,16*4 add edx,16*4 add ebx,16*4 add esi,16*4 loop loopu } } src += n<<4,dst += n<<4,opmul += n<<4,opadd += n<<4; zero: while(cnt--) *(dst++) = *(src++) * *(opmul++) + *(opadd++); } else #elif (FLEXT_CPU == FLEXT_CPU_PPC || FLEXT_CPU == FLEXT_CPU_PPC64) && defined(__VEC__) if(GetSIMDCapabilities()&simd_altivec && VectorsAligned(src,dst,opmul,opadd)) ScaleAltivec(dst,src,opmul,opadd,cnt); else #endif // _MSC_VER #endif // FLEXT_USE_SIMD { int n = cnt>>3; cnt -= n<<3; if(dst == opadd) { while(n--) { dst[0] += src[0]*opmul[0]; dst[1] += src[1]*opmul[1]; dst[2] += src[2]*opmul[2]; dst[3] += src[3]*opmul[3]; dst[4] += src[4]*opmul[4]; dst[5] += src[5]*opmul[5]; dst[6] += src[6]*opmul[6]; dst[7] += src[7]*opmul[7]; src += 8; dst += 8; opmul += 8; } while(cnt--) *(dst++) += *(src++) * *(opmul++); } else { while(n--) { dst[0] = src[0]*opmul[0]+opadd[0]; dst[1] = src[1]*opmul[1]+opadd[1]; dst[2] = src[2]*opmul[2]+opadd[2]; dst[3] = src[3]*opmul[3]+opadd[3]; dst[4] = src[4]*opmul[4]+opadd[4]; dst[5] = src[5]*opmul[5]+opadd[5]; dst[6] = src[6]*opmul[6]+opadd[6]; dst[7] = src[7]*opmul[7]+opadd[7]; src += 8; dst += 8; opmul += 8; opadd += 8; } while(cnt--) *(dst++) = *(src++)* *(opmul++) + *(opadd++); } } #endif } #include "flpopns.h" #endif // __FLEXT_SIMD_CPP flext-0-6-3/source/flsndobj.cpp000066400000000000000000000061311446466241400164610ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #ifndef __FLEXT_SNDOBJ_CPP #define __FLEXT_SNDOBJ_CPP #include "flext.h" #include "flsndobj.h" #include "flpushns.h" flext_sndobj::flext_sndobj(): inobjs(0),outobjs(0), inobj(NULL),tmpobj(NULL),outobj(NULL), smprt(0),blsz(0) {} bool flext_sndobj::Init() { bool ret = flext_dsp::Init(); inobjs = CntInSig(); outobjs = CntOutSig(); return ret; } void flext_sndobj::Exit() { ClearObjs(); flext_dsp::Exit(); } void flext_sndobj::ClearObjs() { FreeObjs(); if(inobj) { for(int i = 0; i < inobjs; ++i) delete inobj[i]; delete[] inobj; inobj = NULL; } if(tmpobj) { for(int i = 0; i < inobjs; ++i) delete tmpobj[i]; delete[] tmpobj; tmpobj = NULL; } if(outobj) { for(int i = 0; i < outobjs; ++i) delete outobj[i]; delete[] outobj; outobj = NULL; } } bool flext_sndobj::CbDsp() { // called on every rebuild of the dsp chain int i; if(Blocksize() != blsz || Samplerate() != smprt) { // block size or sample rate has changed... rebuild all objects ClearObjs(); blsz = Blocksize(); smprt = Samplerate(); // set up sndobjs for inlets and outlets if(inobjs) { inobj = new Inlet *[inobjs]; tmpobj = new SndObj *[inobjs]; for(i = 0; i < inobjs; ++i) { inobj[i] = new Inlet(InSig(i),blsz,smprt); tmpobj[i] = new SndObj(NULL,blsz,smprt); } } if(outobjs) { outobj = new Outlet *[outobjs]; for(i = 0; i < outobjs; ++i) outobj[i] = new Outlet(OutSig(i),blsz,smprt); } if(!NewObjs()) ClearObjs(); } else { // assign changed input/output vectors for(i = 0; i < inobjs; ++i) inobj[i]->SetBuf(InSig(i)); for(i = 0; i < outobjs; ++i) outobj[i]->SetBuf(OutSig(i)); } return true; } void flext_sndobj::CbSignal() { for(int i = 0; i < inobjs; ++i) *tmpobj[i] << *inobj[i]; ProcessObjs(); } flext_sndobj::Inlet::Inlet(const t_sample *b,int vecsz,float sr): SndIO(1,sizeof(t_sample)*8,NULL,vecsz,sr),buf(b) {} short flext_sndobj::Inlet::Read() { if(!m_error) { for(m_vecpos = 0; m_vecpos < m_samples; m_vecpos++) m_output[m_vecpos] = buf[m_vecpos]; return 1; } else return 0; } short flext_sndobj::Inlet::Write() { return 0; } flext_sndobj::Outlet::Outlet(t_sample *b,int vecsz,float sr): SndIO(1,sizeof(t_sample)*8,NULL,vecsz,sr),buf(b) {} short flext_sndobj::Outlet::Read() { return 0; } short flext_sndobj::Outlet::Write() { if(!m_error) { if(m_IOobjs[0]) for(m_vecpos = 0; m_vecpos < m_samples; m_vecpos++) buf[m_vecpos] = m_IOobjs[0]->Output(m_vecpos); return 1; } else return 0; } #include "flpopns.h" #endif // __FLEXT_SNDOBJ_CPP flext-0-6-3/source/flsndobj.h000066400000000000000000000040161446466241400161260ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #ifndef __FLEXT_SNDOBJ_H #define __FLEXT_SNDOBJ_H #include "flext.h" // PI is defined in the Max/MSP SDK, but clashes with SndObj.h #ifdef PI #undef PI #endif // SndObj needs WIN symbol when compiled under Windows #if FLEXT_OS == FLEXT_OS_WIN && !defined(WIN) #define WIN #endif #ifndef FLEXT_THREADS #define NOPTHREAD #endif #include #include #undef NOPTHREAD #include "flpushns.h" class FLEXT_SHARE flext_sndobj: public flext_dsp { FLEXT_HEADER(flext_sndobj,flext_dsp) public: flext_sndobj(); // these have to be overridden in child classes virtual bool NewObjs() { return true; } virtual void FreeObjs() {} virtual void ProcessObjs() {} // inputs and outputs SndObj &InObj(int i) { return *tmpobj[i]; } SndIO &OutObj(int i) { return *outobj[i]; } protected: virtual bool Init(); virtual void Exit(); private: //! SndObj for reading from inlet buffer class Inlet: public SndIO { public: Inlet(const t_sample *b,int vecsz,float sr); virtual short Read(); virtual short Write(); void SetBuf(const t_sample *b) { buf = b; } private: const t_sample *buf; }; //! SndObj for writing to outlet buffer class Outlet: public SndIO { public: Outlet(t_sample *b,int vecsz,float sr); virtual short Read(); virtual short Write(); void SetBuf(t_sample *b) { buf = b; } private: t_sample *buf; }; virtual bool CbDsp(); virtual void CbSignal(); void ClearObjs(); int inobjs,outobjs; SndObj **tmpobj; Inlet **inobj; Outlet **outobj; float smprt; int blsz; }; #include "flpopns.h" #ifdef FLEXT_INLINE # include "flsndobj.cpp" #endif #endif flext-0-6-3/source/flstdc.h000066400000000000000000000225261446466241400156120ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flstdc.h \brief Definitions to unite Max/MSP and PD notions This file contains a few definitions to unite a few of the notions that once drifted apart in Max and PD. It is not elegant but helps. */ #ifndef __FLEXT_STDC_H #define __FLEXT_STDC_H #if defined(_MSC_VER) && (_MSC_VER < 0x1300) /* include math.h here - when included with PD or Max/MSP headers, C linkage would be used which disturbs MSVC6 */ #include #endif #ifdef _MSC_VER #include #endif #include // PD stuff #if FLEXT_SYS == FLEXT_SYS_PD /* PD definitions start here */ #ifdef _MSC_VER #pragma warning (push) #pragma warning (disable:4091 4005) #endif #if FLEXT_OS == FLEXT_OS_WIN && !defined(NT) #define NT #endif extern "C" { // Include the relevant PD header files #ifdef FLEXT_DEBUG /* PD header file structure has changed with version 0.37 from then on m_imp.h needs m_pd.h to be included before on the other hand versions < 0.37 don't like that.... (they want m_imp.h solely as m_pd.h is included therein) So better use the m_pd.h here also for the debug version. Change that if really needed for debugging PD internals... */ #ifndef PD_VERSION // include only if not already included #include #endif // #include // for easier debugging #else #ifndef PD_VERSION // include only if not already included #include #endif #endif } #ifdef _MSC_VER #pragma warning (pop) #endif #include "flpushns.h" #ifdef cabs #undef cabs // this is defined in m_pd.h (clashes with math.h in MacOSX) #endif #define internal_error(fmt, ...) pd_error(NULL, fmt, __VA_ARGS__) typedef t_object t_sigobj; typedef t_gpointer *t_ptrtype; typedef t_float t_flint; typedef t_symbol *t_symtype; typedef t_class **t_thing; typedef t_clock t_qelem; #define A_NOTHING A_NULL #define A_FLINT A_FLOAT #define A_DEFFLINT A_DEFFLOAT #define A_DEFSYMBOL A_DEFSYM #include "flpopns.h" #elif FLEXT_SYS == FLEXT_SYS_MAX /* -------------- Max/MSP ------------------- */ // 2-byte alignment for Max/MSP structures #ifdef _MSC_VER #pragma pack(push,flext_maxsdk) #pragma pack(2) #endif // Include the relevant Max/MSP header files #if FLEXT_OS == FLEXT_OS_MAC #if FLEXT_OSAPI == FLEXT_OSAPI_MAC_MACH // MachO version - must insert prefix header #include #else // CFM version #ifndef __MRC__ #define powerc #endif #define __MOTO__ 0 #include #endif #elif FLEXT_OS == FLEXT_OS_WIN #define WIN_VERSION 1 #define WIN_EXT_VERSION 1 #endif #ifdef FLEXT_USE_MAXAPI // using https://github.com/Cycling74/max-api (usually as part of the Max Devkit package) #include using namespace c74::max; #if MSP64 typedef double t_sample; #else typedef float t_sample; #endif #define _FLEXT_MAX5SDK #else // FLEXT_USE_MAXAPI // necessary for the old OS9 SDK extern "C" { #include "ext.h" #include "ext_user.h" #if FLEXT_OS != FLEXT_OS_MAC || defined(MAC_VERSION) // doesn't exist for OS9 #include "ext_critical.h" #include "buffer.h" #else // for OS9 include "inofficial" header file #include "flmspbuffer.h" #endif #include "z_dsp.h" #include "ext_obex.h" // check for Max5 SDK #include "commonsyms.h" #if C74_MAX_SDK_VERSION >= 0x0500 || COMMON_SYMBOLS_VERSION >= 500 #define _FLEXT_MAX5SDK #endif } // extern "C" #endif // FLEXT_USE_MAXAPI #include "flpushns.h" #undef WIN_VERSION typedef t_pxobject t_sigobj; // that's the all-in-one object type of Max/MSP (not very memory-efficent, i guess) typedef t_patcher t_canvas; typedef t_int t_flint; typedef t_symbol *t_symtype; typedef t_object *t_thing; #ifndef _FLEXT_MAX5SDK // for the following to work you should have the latest SDK #if FLEXT_OS == FLEXT_OS_MAC //&& !defined(MAC_VERSION) typedef struct qelem t_qelem; #else typedef void *t_qelem; #endif #endif #ifndef FLEXT_USE_MAXAPI typedef void t_outlet; #endif typedef method t_method; typedef method t_newmethod; typedef int t_atomtype; #ifndef _FLEXT_MAX5SDK typedef struct clock t_clock; // this is defined in the Max5 SDK #endif typedef void t_binbuf; #undef clock_free #define clock_free(tick) freeobject((object *)tick) #define A_NULL A_NOTHING #define A_DEFFLINT A_DEFLONG #ifndef A_INT #define A_INT A_LONG #endif #ifndef A_DEFINT #define A_DEFINT A_DEFLONG #endif #ifndef A_SYMBOL #define A_SYMBOL A_SYM #endif #ifndef A_DEFSYMBOL #define A_DEFSYMBOL A_DEFSYM #endif #if FLEXT_OS == FLEXT_OS_MAC && !defined(MAC_VERSION) // simulate non-existing functions for OS9 #define critical_enter(N) #define critical_exit(N) #endif #define internal_error error #ifdef _MSC_VER #pragma pack(pop,flext_maxsdk) #endif #include "flpopns.h" #else #error Platform not supported #endif // FLEXT_SYS // general definitions #include "flpushns.h" typedef t_symbol *t_symptr; // ------------------------- #ifdef FLEXT_LOGGING /* If FLEXT_LOGGING is defined implement logging */ #ifdef _MSC_VER #define FLEXT_LOG(s) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s) #define FLEXT_LOG1(s,v1) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1) #define FLEXT_LOG2(s,v1,v2) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1,v2) #define FLEXT_LOG3(s,v1,v2,v3) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1,v2,v3) #define FLEXT_LOG4(s,v1,v2,v3,v4) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1,v2,v3,v4) #define FLEXT_LOG5(s,v1,v2,v3,v4,v5) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1,v2,v3,v4,v5) #define FLEXT_LOG6(s,v1,v2,v3,v4,v5,v6) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1,v2,v3,v4,v5,v6) #define FLEXT_LOG7(s,v1,v2,v3,v4,v5,v6,v7) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1,v2,v3,v4,v5,v6,v7) #define FLEXT_LOG8(s,v1,v2,v3,v4,v5,v6,v7,v8) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1,v2,v3,v4,v5,v6,v7,v8) #define FLEXT_LOG9(s,v1,v2,v3,v4,v5,v6,v7,v8,v9) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",s,v1,v2,v3,v4,v5,v6,v7,v8,v9) #else #define FLEXT_LOG(s) post(s) #define FLEXT_LOG1(s,v1) post(s,v1) #define FLEXT_LOG2(s,v1,v2) post(s,v1,v2) #define FLEXT_LOG3(s,v1,v2,v3) post(s,v1,v2,v3) #define FLEXT_LOG4(s,v1,v2,v3,v4) post(s,v1,v2,v3,v4) #define FLEXT_LOG5(s,v1,v2,v3,v4,v5) post(s,v1,v2,v3,v4,v5) #define FLEXT_LOG6(s,v1,v2,v3,v4,v5,v6) post(s,v1,v2,v3,v4,v5,v6) #define FLEXT_LOG7(s,v1,v2,v3,v4,v5,v6,v7) post(s,v1,v2,v3,v4,v5,v6,v7) #define FLEXT_LOG8(s,v1,v2,v3,v4,v5,v6,v7,v8) post(s,v1,v2,v3,v4,v5,v6,v7,v8) #define FLEXT_LOG9(s,v1,v2,v3,v4,v5,v6,v7,v8,v9) post(s,v1,v2,v3,v4,v5,v6,v7,v8,v9) #endif #else /* If FLEXT_LOGGING is not defined avoid logging */ #define FLEXT_LOG(s) ((void)0) #define FLEXT_LOG1(s,v1) ((void)0) #define FLEXT_LOG2(s,v1,v2) ((void)0) #define FLEXT_LOG3(s,v1,v2,v3) ((void)0) #define FLEXT_LOG4(s,v1,v2,v3,v4) ((void)0) #define FLEXT_LOG5(s,v1,v2,v3,v4,v5) ((void)0) #define FLEXT_LOG6(s,v1,v2,v3,v4,v5,v6) ((void)0) #define FLEXT_LOG7(s,v1,v2,v3,v4,v5,v6,v7) ((void)0) #define FLEXT_LOG8(s,v1,v2,v3,v4,v5,v6,v7,v8) ((void)0) #define FLEXT_LOG9(s,v1,v2,v3,v4,v5,v6,v7,v8,v9) ((void)0) #endif #define FLEXT_UNUSED(x) (void)(x) #ifdef FLEXT_DEBUG #ifdef _MSC_VER #define FLEXT_ASSERT(b) do { if(!(b)) _CrtDbgReport(_CRT_ASSERT,__FILE__,__LINE__,"flext",#b); } while(false) #define FLEXT_WARN(str) _CrtDbgReport(_CRT_WARN,__FILE__,__LINE__,"flext",NULL) #define FLEXT_ERROR(str) _CrtDbgReport(_CRT_ERROR,__FILE__,__LINE__,"flext",NULL) #else #define FLEXT_ASSERT(b) assert(b) //#define FLEXT_ASSERT(b) do { if(!(b)) error("Assertion failed: " #b " - in " __FILE__ " line %i",(int)__LINE__); } while(false) #define FLEXT_WARN(str) internal_error("Warning: in " __FILE__ " line %i",(int)__LINE__) #define FLEXT_ERROR(str) internal_error("Error: in " __FILE__ " line %i",(int)__LINE__) #endif #else #define FLEXT_ASSERT(b) FLEXT_UNUSED(b) #define FLEXT_WARN(str) FLEXT_UNUSED(str) #define FLEXT_ERROR(str) internal_error("Error: in " __FILE__ " line %i",(int)__LINE__) #endif #define ERRINTERNAL() internal_error("flext: Internal error in file " __FILE__ ", line %i - please report",(int)__LINE__) // ----- disable attribute editor for PD version < devel_0_36 or 0.37 #ifndef PD_MAJOR_VERSION # undef FLEXT_NOATTREDIT # define FLEXT_NOATTREDIT #endif // ----- set message queue mode ----- #if FLEXT_SYS == FLEXT_SYS_PD && PD_MINOR_VERSION >= 37 // for PD version >= 0.37test10 FLEXT_PDLOCK is standard # undef FLEXT_PDLOCK # define FLEXT_PDLOCK #endif #ifndef FLEXT_QMODE # if FLEXT_SYS == FLEXT_SYS_PD && PD_MINOR_VERSION >= 38 && defined(PD_DEVEL_VERSION) // use idle callback # define FLEXT_QMODE 1 # elif defined(FLEXT_PDLOCK) // new PD thread locking functionality shall be used # if FLEXT_SYS == FLEXT_SYS_PD # ifdef FLEXT_THREADS // can only be used with PD and threaded build # define FLEXT_QMODE 2 # else # define FLEXT_QMODE 0 # endif # else # error FLEXT_PDLOCK can only be defined with PD # endif # else # define FLEXT_QMODE 0 # endif #endif #ifndef FLEXT_QMODE # error Internal error: Queueing mode not defined #endif #include "flpopns.h" #endif flext-0-6-3/source/flstk.cpp000066400000000000000000000046711446466241400160120ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #ifndef __FLEXT_STK_CPP #define __FLEXT_STK_CPP #include "flext.h" #include "flstk.h" #include "flpushns.h" flext_stk::flext_stk(): inobjs(0),outobjs(0), inobj(NULL),outobj(NULL), smprt(0),blsz(0) {} bool flext_stk::Init() { bool ret = flext_dsp::Init(); inobjs = CntInSig(); outobjs = CntOutSig(); return ret; } void flext_stk::Exit() { ClearObjs(); flext_dsp::Exit(); } void flext_stk::ClearObjs() { FreeObjs(); if(inobj) { for(int i = 0; i < inobjs; ++i) delete inobj[i]; delete[] inobj; inobj = NULL; } if(outobj) { for(int i = 0; i < outobjs; ++i) delete outobj[i]; delete[] outobj; outobj = NULL; } } bool flext_stk::CbDsp() { // called on every rebuild of the dsp chain int i; if(Blocksize() != blsz || Samplerate() != smprt) { // block size or sample rate has changed... rebuild all objects ClearObjs(); smprt = Samplerate(); blsz = Blocksize(); Stk::setSampleRate(smprt); // set up sndobjs for inlets and outlets if(inobjs) { inobj = new Input *[inobjs]; for(i = 0; i < inobjs; ++i) inobj[i] = new Input(InSig(i),blsz); } if(outobjs) { outobj = new Output *[outobjs]; for(i = 0; i < outobjs; ++i) outobj[i] = new Output(OutSig(i),blsz); } if(!NewObjs()) ClearObjs(); } else { // assign changed input/output vectors for(i = 0; i < inobjs; ++i) inobj[i]->SetBuf(InSig(i)); for(i = 0; i < outobjs; ++i) outobj[i]->SetBuf(OutSig(i)); } return true; } void flext_stk::CbSignal() { if(inobjs || outobjs) ProcessObjs(blsz); } // inlet class StkFloat *flext_stk::Input::tick(StkFloat *vector,unsigned int vectorSize) { FLEXT_ASSERT(vectorSize == vecsz); for(unsigned int i = 0; i < vectorSize; i++) vector[i] = tick(); return vector; } // outlet class void flext_stk::Output::tick(const StkFloat *vector,unsigned int vectorSize) { FLEXT_ASSERT(vectorSize == vecsz); for(unsigned int i = 0; i < vectorSize; i++) tick(vector[i]); } #include "flpopns.h" #endif // __FLEXT_STK_CPP flext-0-6-3/source/flstk.h000066400000000000000000000054211446466241400154510ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #ifndef __FLEXT_STK_H #define __FLEXT_STK_H #include "flext.h" // PI is defined in the Max/MSP SDK, but clashes with Stk.h #ifdef PI #undef PI #endif #include #include "flpushns.h" using stk::Stk; using stk::StkFloat; using stk::StkFrames; class FLEXT_SHARE flext_stk: public flext_dsp { FLEXT_HEADER(flext_stk,flext_dsp) public: flext_stk(); // these have to be overridden in child classes virtual bool NewObjs() { return true; } virtual void FreeObjs() {} virtual void ProcessObjs(int blocksize) {} protected: virtual bool Init(); virtual void Exit(); //! STK object for reading from inlet buffer class Input: public Stk { public: Input(const t_sample *b,int v): buf(b),vecsz(v), index(v-1) {} inline StkFloat lastOut() const { return (StkFloat)buf[index]; } inline StkFloat tick() { if(++index >= vecsz) index = 0; return lastOut(); } StkFloat *tick(StkFloat *vector,unsigned int vectorSize); inline StkFrames &tick(StkFrames &vector) { FLEXT_ASSERT(vector.channels() == 1); tick(&vector[0],vector.frames()); return vector; } inline void SetBuf(const t_sample *b) { buf = b; } private: const t_sample *buf; int vecsz,index; }; //! STK object for writing to outlet buffer class Output: public Stk { public: Output(t_sample *b,int v): buf(b),vecsz(v), index(0) {} inline void tick(StkFloat s) { buf[index] = (t_sample)s; if(++index >= vecsz) index = 0; } void tick(const StkFloat *vector,unsigned int vectorSize); inline void tick(const StkFrames &vector) { FLEXT_ASSERT(vector.channels() == 1); // dirty casting due to bug in STK api... operator[] _should_ return const StkFloat & tick(&const_cast(vector)[0],vector.frames()); } inline void SetBuf(t_sample *b) { buf = b; } private: t_sample *buf; int vecsz,index; }; Input &Inlet(int ix) { return *inobj[ix]; } Output &Outlet(int ix) { return *outobj[ix]; } private: virtual bool CbDsp(); virtual void CbSignal(); void ClearObjs(); int inobjs,outobjs; Input **inobj; Output **outobj; float smprt; int blsz; }; #include "flpopns.h" #ifdef FLEXT_INLINE # include "flstk.cpp" #endif #endif flext-0-6-3/source/flsupport.cpp000066400000000000000000000214671446466241400167270ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flsupport.cpp \brief flext support functions and classes. */ #ifndef __FLEXT_SUPPORT_CPP #define __FLEXT_SUPPORT_CPP #include "flext.h" #include #include #include #include #include #include "flpushns.h" #ifdef _MSC_VER #define vsnprintf _vsnprintf #define snprintf _snprintf #endif FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym__ = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_float = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_symbol = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_bang = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_list = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_pointer = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_int = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_signal = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_anything = NULL; #if FLEXT_SYS == FLEXT_SYS_MAX FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_buffer = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_size = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_dirty = NULL; #endif FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_attributes = NULL; FLEXT_TEMPIMPL(const t_symbol *FLEXT_CLASSDEF(flext))::sym_methods = NULL; FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::indsp = false; FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::Version() { return FLEXT_VERSION; } FLEXT_TEMPIMPL(const char *FLEXT_CLASSDEF(flext))::VersionStr() { return FLEXT_VERSTR; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::Setup() { if(sym__) return; #if FLEXT_SYS == FLEXT_SYS_PD sym__ = &s_; sym_anything = &s_anything; sym_pointer = &s_pointer; sym_float = &s_float; sym_symbol = &s_symbol; sym_bang = &s_bang; sym_list = &s_list; sym_signal = &s_signal; sym_int = flext::MakeSymbol("int"); #elif FLEXT_SYS == FLEXT_SYS_MAX sym__ = flext::MakeSymbol(""); sym_int = flext::MakeSymbol("int"); sym_float = flext::MakeSymbol("float"); sym_symbol = flext::MakeSymbol("symbol"); sym_bang = flext::MakeSymbol("bang"); sym_list = flext::MakeSymbol("list"); sym_anything = flext::MakeSymbol("anything"); sym_signal = flext::MakeSymbol("signal"); sym_buffer = flext::MakeSymbol("buffer~"); sym_size = flext::MakeSymbol("size"); sym_dirty = flext::MakeSymbol("dirty"); #endif sym_attributes = flext::MakeSymbol("attributes"); sym_methods = flext::MakeSymbol("methods"); #ifdef FLEXT_THREADS thrid = GetThreadId(); StartHelper(); #endif } #if FLEXT_SYS == FLEXT_SYS_PD && defined(FLEXT_THREADED) && defined(FLEXT_PDLOCK) #define SYSLOCK() sys_lock() #define SYSUNLOCK() sys_unlock() #else #define SYSLOCK() (void)0 #define SYSUNLOCK() (void)0 #endif ///////////////////////////////////////////////////////// // overloaded new/delete memory allocation methods // ///////////////////////////////////////////////////////// #define LARGEALLOC 32000 #ifndef FLEXT_USE_CMEM #ifdef FLEXT_DEBUGMEM static const size_t memtest = 0x12345678L; #endif FLEXT_TEMPIMPL(void *FLEXT_CLASSDEF(flext_root))::operator new(size_t bytes) { bytes += sizeof(size_t); #ifdef FLEXT_DEBUGMEM bytes += sizeof(memtest)*2; #endif char *blk; if(UNLIKELY(bytes >= LARGEALLOC)) { #if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_) blk = (char *)sysmem_newptr(bytes); #else // use C library function for large memory blocks blk = (char *)malloc(bytes); #endif } else { //! We need system locking here for secondary threads! SYSLOCK(); blk = (char *)getbytes(bytes); SYSUNLOCK(); } FLEXT_ASSERT(blk); *(size_t *)blk = bytes; #ifdef FLEXT_DEBUGMEM *(size_t *)(blk+sizeof(size_t)) = memtest; *(size_t *)(blk+bytes-sizeof(memtest)) = memtest; return blk+sizeof(size_t)+sizeof(memtest); #else return blk+sizeof(size_t); #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_root))::operator delete(void *blk) { if(!blk) return; FLEXT_ASSERT(MemCheck(blk)); #ifdef FLEXT_DEBUGMEM char *ori = (char *)blk-sizeof(size_t)-sizeof(memtest); #else char *ori = (char *)blk-sizeof(size_t); #endif size_t bytes = *(size_t *)ori; if(UNLIKELY(bytes >= LARGEALLOC)) { #if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_) sysmem_freeptr(ori); #else // use C library function for large memory blocks free(ori); #endif } else { //! We need system locking here for secondary threads! SYSLOCK(); freebytes(ori,bytes); SYSUNLOCK(); } } #ifdef FLEXT_DEBUGMEM FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_root))::MemCheck(void *blk) { char *ori = (char *)blk-sizeof(size_t)-sizeof(memtest); size_t bytes = *(size_t *)ori; return *(size_t *)((char *)ori+sizeof(size_t)) == memtest && *(size_t *)((char *)ori+bytes-sizeof(memtest)) == memtest; } #endif #endif FLEXT_TEMPIMPL(void *FLEXT_CLASSDEF(flext_root))::NewAligned(size_t bytes,int bitalign) { const size_t ovh = sizeof(size_t)+sizeof(char *); const size_t alignovh = bitalign/8-1; bytes += ovh+alignovh; char *blk; if(UNLIKELY(bytes >= LARGEALLOC)) { #if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_) blk = (char *)sysmem_newptr(bytes); #else // use C library function for large memory blocks blk = (char *)malloc(bytes); #endif } else { //! We need system locking here for secondary threads! SYSLOCK(); #if defined(FLEXT_USE_CMEM) blk = (char *)malloc(bytes); #else blk = (char *)getbytes(bytes); #endif SYSUNLOCK(); } FLEXT_ASSERT(blk); char *ablk = reinterpret_cast((reinterpret_cast(blk)+ovh+alignovh) & ~alignovh); *(char **)(ablk-sizeof(size_t)-sizeof(char *)) = blk; *(size_t *)(ablk-sizeof(size_t)) = bytes; return ablk; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_root))::FreeAligned(void *blk) { FLEXT_ASSERT(blk); char *ori = *(char **)((char *)blk-sizeof(size_t)-sizeof(char *)); size_t bytes = *(size_t *)((char *)blk-sizeof(size_t)); if(UNLIKELY(bytes >= LARGEALLOC)) { #if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_) sysmem_freeptr(ori); #else // use C library function for large memory blocks free(ori); #endif } else { //! We need system locking here for secondary threads! SYSLOCK(); #if defined(FLEXT_USE_CMEM) free(ori); #else freebytes(ori,bytes); #endif SYSUNLOCK(); } } // ------------------------------------------ #if defined(FLEXT_USE_CMEM) // define global new/delete operators void *operator new(size_t bytes) NEWTHROW { return flext_root::operator new(bytes); } void operator delete(void *blk) DELTHROW { flext_root::operator delete(blk); } #ifndef __MRC__ // doesn't allow new[] overloading?! void *operator new[](size_t bytes) NEWTHROW { return flext_root::operator new[](bytes); } void operator delete[](void *blk) DELTHROW { flext_root::operator delete[](blk); } #endif #endif // FLEXT_USE_CMEM // ------------------------------------------ /*! \todo there is probably also a shortcut for Max \todo size checking */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::GetAString(const t_atom &a,char *buf,size_t szbuf) { #if FLEXT_SYS == FLEXT_SYS_PD atom_string(const_cast(&a),buf,(int)szbuf); #else if(IsSymbol(a)) STD::strncpy(buf,GetString(a),szbuf); else if(IsFloat(a)) STD::snprintf(buf,szbuf,"%f",GetFloat(a)); else if(IsInt(a)) STD::snprintf(buf,szbuf,"%i",GetInt(a)); else *buf = 0; #endif } FLEXT_TEMPIMPL(unsigned long FLEXT_CLASSDEF(flext))::AtomHash(const t_atom &a) { #if FLEXT_SYS == FLEXT_SYS_MAX || FLEXT_SYS == FLEXT_SYS_PD return ((unsigned long)a.a_type<<28)^*(unsigned long *)&a.a_w; #else #error Not implemented #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_root))::post(const char *fmt, ...) { va_list ap; va_start(ap, fmt); char buf[1024]; vsnprintf(buf,sizeof buf,fmt, ap); buf[sizeof buf-1] = 0; // in case of full buffer #if FLEXT_SYS == FLEXT_SYS_MAX && C74_MAX_SDK_VERSION >= 0x0500 ::object_post(NULL,buf); #else ::post(buf); #endif va_end(ap); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_root))::error(const char *fmt,...) { va_list ap; va_start(ap, fmt); char buf[1024]; STD::strcpy(buf,"error: "); vsnprintf(buf+7,sizeof buf-7,fmt, ap); buf[sizeof buf-1] = 0; // in case of full buffer #if FLEXT_SYS == FLEXT_SYS_MAX #if C74_MAX_SDK_VERSION >= 0x0500 ::object_error(NULL,buf); #else ::error(buf); #endif #else ::post(buf); #endif va_end(ap); } #include "flpopns.h" #endif // __FLEXT_SUPPORT_CPP flext-0-6-3/source/flsupport.h000066400000000000000000001406101446466241400163640ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2020 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flsupport.h \brief flext support functions and classes */ #ifndef __FLSUPPORT_H #define __FLSUPPORT_H #include "flstdc.h" #include #include #include "flpushns.h" #if C74_MAX_SDK_VERSION >= 0x0610 // really bad: post and error are #defines in Max SDK >= 610 #undef post #undef error #endif /*! \defgroup FLEXT_SUPPORT Flext support classes @{ */ FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_root); typedef FLEXT_TEMPINST(FLEXT_SHARE FLEXT_CLASSDEF(flext_root)) flext_root; /*! \brief Flext root support class Moved memory functions and console output here so that all the classes contained in flext can use them */ FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_root) { public: // --- console output ----------------------------------------------- //! post message to console, with line feed (limited to 1k chars!) static void post(const char *fmt,...); //! post error message to console (limited to 1k chars!) static void error(const char *fmt,...); // --- memory ------------------------------------------------------- /*! \defgroup FLEXT_S_MEMORY Memory allocation functions @{ */ #ifdef FLEXT_NOGLOBALNEW #error FLEXT_NOGLOBALNEW is deprecated, define FLEXT_USE_CMEM instead #define FLEXT_USE_CMEM #endif #ifdef FLEXT_USE_CMEM inline void *operator new(size_t bytes) { return ::operator new(bytes); } inline void operator delete(void *blk) { ::operator delete(blk); } inline void *operator new[](size_t bytes) { return ::operator new[](bytes); } inline void operator delete[](void *blk) { ::operator delete[](blk); } static bool MemCheck(void *) { return true; } #else /*! Overloaded new memory allocation method \note this uses a fast allocation method of the real-time system \warning Max/MSP (or MacOS) allows only 32K in overdrive mode! */ void *operator new(size_t bytes); //! Overloaded delete method void operator delete(void *blk); #ifndef __MRC__ // doesn't allow new[] overloading?! inline void *operator new[](size_t bytes) { return operator new(bytes); } inline void operator delete[](void *blk) { operator delete(blk); } #endif #ifdef FLEXT_DEBUGMEM static bool MemCheck(void *blk); #else static bool MemCheck(void *) { return true; } #endif #endif // USECMEM #ifndef __BORLANDC__ inline void *operator new(size_t,void *p) { return p; } inline void operator delete(void *,void *) {} #ifndef __MRC__ inline void *operator new[](size_t,void *p) { return p; } inline void operator delete[](void *,void *) {} #endif #endif //! Get an aligned memory block static void *NewAligned(size_t bytes,int bitalign = 128); // same with templated type template static T *NewAligned(size_t times,int bitalign = 128) { return static_cast(NewAligned(times*sizeof(T),bitalign)); } //! Free an aligned memory block static void FreeAligned(void *blk); //! Test for alignment static bool IsAligned(void *ptr,int bitalign = 128) { return (reinterpret_cast(ptr)&(bitalign-1)) == 0; } //! @} FLEXT_S_MEMORY }; #ifdef FLEXT_USE_CMEM # define NEWTHROW # define DELTHROW #else // MFC doesn't like global overloading of allocators // anyway, who likes MFC #if !defined(_MSC_VER) && !defined(__BORLANDC__) #if __cpp_noexcept_function_type # define NEWTHROW noexcept(false) # define DELTHROW noexcept(true) #else # define NEWTHROW throw(std::bad_alloc) # define DELTHROW throw() #endif #else # define NEWTHROW # define DELTHROW #endif // define global new/delete operators void *operator new(size_t bytes) NEWTHROW; void operator delete(void *blk) DELTHROW; #ifndef __MRC__ // doesn't allow new[] overloading?! void *operator new[](size_t bytes) NEWTHROW; void operator delete[](void *blk) DELTHROW; #endif #endif // FLEXT_USE_CMEM /************************************************************************/ FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext); typedef FLEXT_TEMPINST(FLEXT_CLASSDEF(flext)) flext; FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext_base); /*! \brief Flext support class A number of methods (most are static functions) are defined here for convenience. This class doesn't define any data members, hence it can be inherited to all classes (not only PD objects) to profit from the cross-platform functionality. Examples are the overloaded memory allocation, atom and atom list functions, thread functions and classes, the sample buffer class and others. This class can also be used for a non-object class (not representing an external object) and won't give any extra burden to it. */ FLEXT_TEMPLATE class FLEXT_SHARE FLEXT_CLASSDEF(flext): public flext_root { /*! \defgroup FLEXT_SUPPORT Flext support class @{ */ public: // --- version ----------------------------------------------- /*! \brief Flext version number Return the version number of the flext library. For statically linked flext this is identical to the header definition FLEXT_VERSION, otherwise it reflects the version number of the shared flext library. */ static int Version(); //! Flext version string static const char *VersionStr(); // --- special typedefs --------------------------------------------- // later! #if 0 typedef t_float Float; typedef t_int Int; typedef t_sample Sample; typedef const t_symbol *Symbol; typedef t_atom Atom; #endif // --- buffer/array stuff ----------------------------------------- /*! \defgroup FLEXT_S_BUFFER Buffer handling @{ */ //! Class for platform independent buffer handling class FLEXT_SHARE buffer: public flext_root { public: #if FLEXT_SYS == FLEXT_SYS_PD typedef bool lock_t; #elif FLEXT_SYS == FLEXT_SYS_MAX typedef long lock_t; #else #error Not implemented #endif // PD 64-bit buffer handling macros #if FLEXT_SYS == FLEXT_SYS_PD # if PD_MINOR_VERSION >= 41 /* use new garray support that is 64-bit safe */ # define FLEXT_PD_ARRAYGRAB garray_getfloatwords # define FLEXT_ARRAYTYPE t_word # define FLEXT_GETSAMPLE(x) ((x).w_float) # define _FLEXT_NEED_SAMPLE_CONV 1 # else /* use old garray support, not 64-bit safe */ # define FLEXT_PD_ARRAYGRAB garray_getfloatarray # define FLEXT_ARRAYTYPE t_sample # define FLEXT_GETSAMPLE(x) (x) # define _FLEXT_NEED_SAMPLE_CONV 0 # endif #elif FLEXT_SYS == FLEXT_SYS_MAX # define FLEXT_ARRAYTYPE float # define FLEXT_GETSAMPLE(x) (x) # define _FLEXT_NEED_SAMPLE_CONV 0 #endif class Element { public: Element() {} Element(FLEXT_ARRAYTYPE s): el(s) {} operator FLEXT_ARRAYTYPE &() { return el; } operator FLEXT_ARRAYTYPE () const { return el; } #if _FLEXT_NEED_SAMPLE_CONV Element(t_sample s) { FLEXT_GETSAMPLE(el) = s; } operator t_sample &() { return FLEXT_GETSAMPLE(el); } operator t_sample () const { return FLEXT_GETSAMPLE(el); } #endif protected: FLEXT_ARRAYTYPE el; }; /*! \brief Construct buffer. \param s: symbol name, can be NULL \param delayed = true: only sets name, needs another Set(NULL) to really initialize the buffer \remark As externals can be created prior to the buffer objects they are pointing to, initialization should be done at loadbang! */ buffer(const t_symbol *s = NULL,bool delayed = false); //! Destroy buffer ~buffer(); /*! \brief Check if the buffer is valid for use \note This must be true to use any of the other functions except set */ bool Ok() const { return sym #if FLEXT_SYS == FLEXT_SYS_PD && arr #endif && data; } /*! \brief Check if buffer content is valid (not in state of content change) \note buffer must be Ok() */ bool Valid() const { FLEXT_ASSERT(sym); #if FLEXT_SYS == FLEXT_SYS_PD return true; #elif FLEXT_SYS == FLEXT_SYS_MAX const t_buffer *p = (const t_buffer *)sym->s_thing; return p && p->b_valid; #else #error not implemented #endif } /*! \brief Check and update if the buffer has been changed (e.g. resized) \note buffer must be Ok() */ bool Update(); /*! \brief Lock buffer \return previous state (needed for Unlock) \note buffer must be Ok() */ lock_t Lock(); /*! \brief Unlock buffer \param prv: Previous state is returned by Lock() \note buffer must be Ok() */ void Unlock(lock_t prv); /*! \brief Set to specified buffer. \param nameonly: if true sets name only, but doesn't look at buffer actually \return -1 on failure, 0 on success, 1 if parameters (length, data ptr, channels) have changed */ int Set(const t_symbol *s = NULL,bool nameonly = false); /*! \brief Declare buffer content as dirty. \param refr: if true forces immediate graphics refresh */ void Dirty(bool refr = false); //! Clear the dirty flag. void ClearDirty(); /*! Query whether the buffer content has been changed since the last ClearDirty() \note With mainstream versions of PD this will always return true, since the dirtiness can't be judged */ bool IsDirty() const; //! Get symbol of buffer const t_symbol *Symbol() const { return sym; } //! Get literal name of buffer const char *Name() const { return sym?GetString(sym):""; } /*! \brief Get pointer to buffer, channel and frame count. \remark Channels are interleaved */ Element *Data() { return data; } const Element *Data() const { return data; } //! Get channel count int Channels() const { return chns; } //! Get frame count int Frames() const { return frames; } //! Set frame count void Frames(int fr,bool keep = false,bool zero = true); //! Get data value in a platform-independent way inline Element operator [](int index) const { return data[index]; } //! Reference data value in a platform-independent way inline Element &operator [](int index) { return data[index]; } //! Graphic auto refresh interval void SetRefrIntv(float intv); //! Buffer locking class class Locker { public: Locker(buffer &b): buf(b),lock(b.Lock()) {} ~Locker() { buf.Unlock(lock); } private: buffer &buf; lock_t lock; }; protected: //! buffer name const t_symbol *sym; //! array holding audio data Element *data; //! number of audio channels int chns; //! number of frames (multiplied by chns for the number of samples) int frames; #if FLEXT_SYS == FLEXT_SYS_PD //! pointer to the PD array structure t_garray *arr; //! update interval float interval; //! flag signaling that the data has been changed bool isdirty; //! flag showing that the update clock is active bool ticking; //! update clock t_clock *tick; //! last time the dirty flag was cleared (using the clock_getlogicaltime function) double cleantime; private: //! update clock callback static void cb_tick(buffer *b); #elif FLEXT_SYS == FLEXT_SYS_MAX //! last time the dirty flag was cleared (using the gettime function) long cleantime; #endif }; //! @} FLEXT_S_BUFFER // --- utilities -------------------------------------------------- /*! \defgroup FLEXT_S_UTIL Utility functions @{ */ //! Copy an atom static void CopyAtom(t_atom *dst,const t_atom *src) { *dst = *src; } //! Copy atoms static void CopyAtoms(int cnt,t_atom *dst,const t_atom *src); //! Print an atom static bool PrintAtom(const t_atom &a,char *buf,size_t bufsz); /*! Scan an atom until whitespace \return next token position, or NULL on failure */ static const char *ScanAtom(t_atom &a,const char *buf); //! Copy a list of atoms static t_atom *CopyList(int argc,const t_atom *argv); //! Print an atom list static bool PrintList(int argc,const t_atom *argv,char *buf,size_t bufsz); /*! Scan an atom list \param argc ... maximum amount of atoms scanned \param argv ... array of atoms \param buf ... char buffer */ static int ScanList(int argc,t_atom *argv,const char *buf); //! Copy a memory region static void CopyMem(void *dst,const void *src,int bytes); //! Copy a sample array static void CopySamples(t_sample *dst,const t_sample *src,int cnt); template static void CopySamples(T *dst,const T *src,int cnt) { CopyMem(dst,src,sizeof(*src)*cnt); } //! Set a memory region static void ZeroMem(void *dst,int bytes); //! Set a sample array to a fixed value static void SetSamples(t_sample *dst,int cnt,t_sample s); template static void SetSamples(T *dst,int cnt,t_sample s) { for(int i = 0; i < cnt; ++i) dst[i] = s; } //! Set a sample array to 0 static void ZeroSamples(t_sample *dst,int cnt) { SetSamples(dst,cnt,0); } template static void ZeroSamples(T *dst,int cnt) { ZeroMem(dst,sizeof(*dst)*cnt); } //! Get a 32 bit hash value from an atom static unsigned long AtomHash(const t_atom &a); //! @} FLEXT_S_UTIL // --- various symbols -------------------------------------------- /*! \defgroup FLEXT_S_ATOM Atom/list handling @{ */ //! Symbol constant for "" static const t_symbol *sym__; //! Symbol constant for "float" static const t_symbol *sym_float; //! Symbol constant for "symbol" static const t_symbol *sym_symbol; //! Symbol constant for "bang" static const t_symbol *sym_bang; //! Symbol constant for "list" static const t_symbol *sym_list; //! Symbol constant for "anything" static const t_symbol *sym_anything; /*! \brief Symbol constant for "int" \note Only the Max/MSP system has this defined as an internal type */ static const t_symbol *sym_int; /*! Symbol constant for "pointer" \note Only PD has this defined as an internal type */ static const t_symbol *sym_pointer; //! Symbol constant for "signal" static const t_symbol *sym_signal; //! \note This is used in macros where the type of the arg is not clear static const t_symbol *MakeSymbol(const t_symbol *s) { return s; } //! Make a symbol from a string static const t_symbol *MakeSymbol(const char *s) { return ::gensym(const_cast(s)); } //! Get symbol string static const char *GetString(const t_symbol *s) { return s->s_name; } //! Check for symbol and get string static const char *GetAString(const t_symbol *s,const char *def = NULL) { return s?GetString(s):def; } // --- atom stuff ---------------------------------------- //! Set atom from another atom static void SetAtom(t_atom &a,const t_atom &b) { CopyAtom(&a,&b); } //! Compare two atoms static int CmpAtom(const t_atom &a,const t_atom &b); // there are some more comparison functions for t_atom types outside the class //! Set atom from another atom static int GetType(const t_atom &a) { return a.a_type; } //! Check whether the atom is nothing static bool IsNothing(const t_atom &a) { return a.a_type == A_NULL; } //! Set the atom to represent nothing static void SetNothing(t_atom &a) { a.a_type = A_NULL; } //! Check whether the atom is a float static bool IsFloat(const t_atom &a) { return a.a_type == A_FLOAT; } //! Check whether the atom can be represented as a float static bool CanbeFloat(const t_atom &a) { return IsFloat(a) || IsInt(a); } //! Access the float value (without type check) static float GetFloat(const t_atom &a) { return a.a_w.w_float; } //! Set the atom to represent a float static void SetFloat(t_atom &a,float v) { a.a_type = A_FLOAT; a.a_w.w_float = v; } //! Check whether the atom is a symbol static bool IsSymbol(const t_atom &a) { return a.a_type == A_SYMBOL; } #if FLEXT_SYS == FLEXT_SYS_PD //! Access the symbol value (without type check) static const t_symbol *GetSymbol(const t_atom &a) { return const_cast(a.a_w.w_symbol); } //! Set the atom to represent a symbol static void SetSymbol(t_atom &a,const t_symbol *s) { a.a_type = A_SYMBOL; a.a_w.w_symbol = const_cast(s); } #elif FLEXT_SYS == FLEXT_SYS_MAX //! Access the symbol value (without type check) static const t_symbol *GetSymbol(const t_atom &a) { return const_cast(a.a_w.w_sym); } //! Set the atom to represent a symbol static void SetSymbol(t_atom &a,const t_symbol *s) { a.a_type = A_SYMBOL; a.a_w.w_sym = const_cast(s); } #else #error #endif //! Check for a symbol and get its value static const t_symbol *GetASymbol(const t_atom &a,const t_symbol *def = NULL) { return IsSymbol(a)?GetSymbol(a):def; } // NULL or empty symbol? //! Check whether the atom is a string static bool IsString(const t_atom &a) { return IsSymbol(a); } //! Access the string value (without type check) static const char *GetString(const t_atom &a) { const t_symbol *s = GetSymbol(a); return s?GetString(s):NULL; } //! Check for a string and get its value static const char *GetAString(const t_atom &a,const char *def = NULL) { return IsSymbol(a)?GetAString(GetSymbol(a),def):def; } //! Check for a string and get its value static void GetAString(const t_atom &a,char *buf,size_t szbuf); //! Set the atom to represent a string static void SetString(t_atom &a,const char *c) { SetSymbol(a,MakeSymbol(c)); } //! Check whether the atom can be represented as an integer static bool CanbeInt(const t_atom &a) { return IsFloat(a) || IsInt(a); } #if FLEXT_SYS == FLEXT_SYS_PD //! Check for a float and get its value static float GetAFloat(const t_atom &a,float def = 0) { return IsFloat(a)?GetFloat(a):def; } //! Check whether the atom is an integer static bool IsInt(const t_atom &) { return false; } //! Access the integer value (without type check) static int GetInt(const t_atom &a) { return (int)GetFloat(a); } //! Check for an integer and get its value static int GetAInt(const t_atom &a,int def = 0) { return (int)GetAFloat(a,(float)def); } //! Set the atom to represent a integer (depending on the system) static void SetInt(t_atom &a,int v) { a.a_type = A_FLOAT; a.a_w.w_float = (float)v; } #ifndef FLEXT_COMPATIBLE //! Check whether the atom strictly is a pointer static bool IsPointer(const t_atom &a) { return a.a_type == A_POINTER; } //! Check whether the atom can be a pointer static bool CanbePointer(const t_atom &a) { return IsPointer(a); } //! Access the pointer value (without type check) static t_gpointer *GetPointer(const t_atom &a) { return a.a_w.w_gpointer; } //! Check for a pointer and get its value static t_gpointer *GetAPointer(const t_atom &a,t_gpointer *def = NULL) { return IsPointer(a)?GetPointer(a):def; } //! Set the atom to represent a pointer static void SetPointer(t_atom &a,t_gpointer *p) { a.a_type = A_POINTER; a.a_w.w_gpointer = (t_gpointer *)p; } #endif #elif FLEXT_SYS == FLEXT_SYS_MAX //! Check for a float and get its value static float GetAFloat(const t_atom &a,float def = 0) { return IsFloat(a)?GetFloat(a):(IsInt(a)?GetInt(a):def); } //! Check whether the atom is an int static bool IsInt(const t_atom &a) { return a.a_type == A_INT; } //! Access the integer value (without type check) static int GetInt(const t_atom &a) { return a.a_w.w_long; } //! Check for an integer and get its value static int GetAInt(const t_atom &a,int def = 0) { return IsInt(a)?GetInt(a):(IsFloat(a)?(int)GetFloat(a):def); } //! Set the atom to represent an integer static void SetInt(t_atom &a,int v) { a.a_type = A_INT; a.a_w.w_long = v; } #else #error "Platform not supported" #endif // bool type - based on int //! Set the atom to represent a boolean static void SetBool(t_atom &a,bool v) { SetInt(a,v?1:0); } //! Check whether the atom can be represented as a boolean static bool CanbeBool(const t_atom &a) { return CanbeInt(a); } //! Check for an boolean and get its value static bool GetABool(const t_atom &a) { return GetAInt(a) != 0; } //! Check for an boolean and get its value static bool GetBool(const t_atom &a) { return GetInt(a) != 0; } // --- atom list stuff ------------------------------------------- //! Class representing a list of atoms class FLEXT_SHARE AtomList : public flext_root { public: //! Construct list AtomList(): cnt(0),lst(NULL) {} //! Construct list explicit AtomList(int argc,const t_atom *argv = NULL): cnt(0),lst(NULL) { operator()(argc,argv); } //! Construct list AtomList(const AtomList &a): cnt(0),lst(NULL) { operator =(a); } //! Destroy list virtual ~AtomList(); //! Clear list AtomList &Clear() { return operator()(); } //! Set list AtomList &Set(int argc,const t_atom *argv,int offs = 0,bool resize = false); //! Get list int Get(t_atom *argv,int mxsz = -1) const; //! Set list AtomList &operator()(int argc = 0,const t_atom *argv = NULL) { return Set(argc,argv,0,true); } //! Set list by another AtomList AtomList &operator =(const AtomList &a) { return operator()(a.Count(),a.Atoms()); } //! Compare list to another AtomList ( -1..< , 0..==, 1...> ) int Compare(const AtomList &a) const; bool operator <(const AtomList &a) const { return Compare(a) < 0; } bool operator <=(const AtomList &a) const { return Compare(a) <= 0; } bool operator >(const AtomList &a) const { return Compare(a) > 0; } bool operator >=(const AtomList &a) const { return Compare(a) >= 0; } bool operator ==(const AtomList &a) const { return Compare(a) == 0; } bool operator !=(const AtomList &a) const { return Compare(a) != 0; } //! Get number of atoms in the list int Count() const { return cnt; } //! Get a reference to an indexed atom t_atom &operator [](int ix) { return lst[ix]; } //! Get a reference to an indexed atom const t_atom &operator [](int ix) const { return lst[ix]; } //! Get a pointer to the list of atoms t_atom *Atoms() { return lst; } //! Get a pointer to the list of atoms const t_atom *Atoms() const { return lst; } //! Append an atom list to the list AtomList &Append(int argc,const t_atom *argv = NULL) { int c = Count(); Alloc(c+argc,0,c); Set(argc,argv,c); return *this; } //! Prepend an atom list to the list AtomList &Prepend(int argc,const t_atom *argv = NULL) { int c = Count(); Alloc(c+argc,0,c,argc); Set(argc,argv); return *this; } //! Append an atom to the list AtomList &Append(const t_atom &a) { return Append(1,&a); } //! Append an atom list to the list AtomList &Append(const AtomList &a) { return Append(a.Count(),a.Atoms()); } //! Prepend an atom to the list AtomList &Prepend(const t_atom &a) { return Prepend(1,&a); } //! Prepend an atom list to the list AtomList &Prepend(const AtomList &a) { return Prepend(a.Count(),a.Atoms()); } //! Get a part of the list void GetPart(int offs,int len,AtomList &ret) const; //! Set to a part of the list AtomList &Part(int offs,int len) { GetPart(offs,len,*this); return *this; } //! Represent as a string bool Print(char *buffer,int buflen) const { return flext::PrintList(Count(),Atoms(),buffer,buflen); } /*! Read from string \note: doesn't clear or reallocate the list */ int Scan(const char *buffer) { return flext::ScanList(Count(),Atoms(),buffer); } protected: virtual void Alloc(int sz,int keepix = -1,int keeplen = -1,int keepto = 0); virtual void Free(); int cnt; t_atom *lst; }; class FLEXT_SHARE AtomListStaticBase : public AtomList { protected: explicit AtomListStaticBase(int pc,t_atom *dt): precnt(pc),predata(dt) {} virtual ~AtomListStaticBase(); virtual void Alloc(int sz,int keepix = -1,int keeplen = -1,int keepto = 0); virtual void Free(); AtomListStaticBase &operator =(const AtomList &a) { AtomList::operator =(a); return *this; } AtomListStaticBase &operator =(const AtomListStaticBase &a) { AtomList::operator =(a); return *this; } const int precnt; t_atom *const predata; }; template class AtomListStatic : public AtomListStaticBase { public: //! Construct list explicit AtomListStatic(): AtomListStaticBase(PRE,pre) {} //! Construct list explicit AtomListStatic(int argc,const t_atom *argv = NULL): AtomListStaticBase(PRE,pre) { AtomList::operator()(argc,argv); } //! Construct list explicit AtomListStatic(const AtomList &a): AtomListStaticBase(PRE,pre) { operator =(a); } //! Set list by another AtomList AtomListStatic &operator =(const AtomList &a) { AtomListStaticBase::operator =(a); return *this; } AtomListStatic &operator =(const AtomListStatic &a) { AtomListStaticBase::operator =(a); return *this; } protected: t_atom pre[PRE]; }; //! Class representing an "anything" class FLEXT_SHARE AtomAnything: public AtomList { public: explicit AtomAnything(): hdr(NULL) {} //! Construct anything explicit AtomAnything(const t_symbol *h,int argc = 0,const t_atom *argv = NULL) : AtomList(argc,argv),hdr(h?h:sym__) {} //! Construct anything explicit AtomAnything(const char *h,int argc = 0,const t_atom *argv = NULL) : AtomList(argc,argv),hdr(MakeSymbol(h)) {} //! Construct anything AtomAnything(const AtomAnything &a) : AtomList(a),hdr(a.hdr) {} //! Clear anything AtomAnything &Clear() { return operator()(); } //! Get header symbol of anything const t_symbol *Header() const { return hdr; } //! Set header symbol of anything void Header(const t_symbol *h) { hdr = h; } //! Set anything AtomAnything &operator()(const t_symbol *h = NULL,int argc = 0,const t_atom *argv = NULL) { hdr = h; AtomList::operator()(argc,argv); return *this; } //! Set list by another AtomAnything AtomAnything &operator =(const AtomAnything &a) { return operator()(a.Header(),a.Count(),a.Atoms()); } protected: const t_symbol *hdr; }; // double type - based on two floats #ifdef _MSC_VER #pragma optimize("p",off) // improve floating point precision consistency #endif static t_atom *SetDouble(t_atom *dbl,double d) { float f = static_cast(d); float r = static_cast(d-f); SetFloat(dbl[0],f); SetFloat(dbl[1],r); return dbl; } #ifdef _MSC_VER #pragma optimize("p",on) #endif static double GetDouble(int argc,const t_atom *argv) { double d = argc >= 1?GetAFloat(argv[0]):0; return argc >= 2?d+GetAFloat(argv[1]):d; } static AtomList &SetDouble(AtomList &l,double d) { SetDouble(l(2).Atoms(),d); return l; } static double GetDouble(const AtomList &l) { return GetDouble(l.Count(),l.Atoms()); } //! @} FLEXT_S_ATOM // --- messages ------------------------------------------------------- /*! \defgroup FLEXT_S_MSGBUNDLE Flext message handling @{ */ class MsgBundle; //! Make new message bundle static MsgBundle *MsgNew(); //! Destroy message bundle static void MsgFree(MsgBundle *mb); //! Send (and destroy) message bundle static void ToSysMsg(MsgBundle *mb); //! Send (and destroy) message bundle static void ToOutMsg(MsgBundle *mb); //! Send low priority (and destroy) message bundle static void ToQueueMsg(MsgBundle *mb); //! @} FLEXT_S_MSGBUNDLE /*! \defgroup FLEXT_S_MSG Flext message handling @{ */ static bool Forward(const t_symbol *sym,const t_symbol *s,int argc,const t_atom *argv); static bool Forward(const t_symbol *sym,const AtomAnything &args) { return Forward(sym,args.Header(),args.Count(),args.Atoms()); } static bool Forward(const char *sym,const AtomAnything &args) { return Forward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); } static bool Forward(const t_symbol *sym,int argc,const t_atom *argv) { return Forward(sym,sym_list,argc,argv); } static bool Forward(const t_symbol *sym,const AtomList &args) { return Forward(sym,args.Count(),args.Atoms()); } static bool Forward(const char *sym,const AtomList &args) { return Forward(MakeSymbol(sym),args.Count(),args.Atoms()); } static bool SysForward(const t_symbol *sym,const t_symbol *s,int argc,const t_atom *argv); static bool SysForward(const t_symbol *sym,const AtomAnything &args) { return SysForward(sym,args.Header(),args.Count(),args.Atoms()); } static bool SysForward(const char *sym,const AtomAnything &args) { return SysForward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); } static bool SysForward(const t_symbol *sym,int argc,const t_atom *argv) { return SysForward(sym,sym_list,argc,argv); } static bool SysForward(const t_symbol *sym,const AtomList &args) { return SysForward(sym,args.Count(),args.Atoms()); } static bool SysForward(const char *sym,const AtomList &args) { return SysForward(MakeSymbol(sym),args.Count(),args.Atoms()); } static bool QueueForward(const t_symbol *sym,const t_symbol *s,int argc,const t_atom *argv); static bool QueueForward(const t_symbol *sym,const AtomAnything &args) { return QueueForward(sym,args.Header(),args.Count(),args.Atoms()); } static bool QueueForward(const char *sym,const AtomAnything &args) { return QueueForward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); } static bool QueueForward(const t_symbol *sym,int argc,const t_atom *argv) { return QueueForward(sym,sym_list,argc,argv); } static bool QueueForward(const t_symbol *sym,const AtomList &args) { return QueueForward(sym,args.Count(),args.Atoms()); } static bool QueueForward(const char *sym,const AtomList &args) { return QueueForward(MakeSymbol(sym),args.Count(),args.Atoms()); } static bool MsgForward(MsgBundle *mb,const t_symbol *sym,const t_symbol *s,int argc,const t_atom *argv); static bool MsgForward(MsgBundle *mb,const t_symbol *sym,const AtomAnything &args) { return MsgForward(mb,sym,args.Header(),args.Count(),args.Atoms()); } static bool MsgForward(MsgBundle *mb,const char *sym,const AtomAnything &args) { return MsgForward(mb,MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); } static bool MsgForward(MsgBundle *mb,const t_symbol *sym,int argc,const t_atom *argv) { return MsgForward(mb,sym,sym_list,argc,argv); } static bool MsgForward(MsgBundle *mb,const t_symbol *sym,const AtomList &args) { return MsgForward(mb,sym,args.Count(),args.Atoms()); } static bool MsgForward(MsgBundle *mb,const char *sym,const AtomList &args) { return MsgForward(mb,MakeSymbol(sym),args.Count(),args.Atoms()); } //! @} FLEXT_S_MSG // --- thread stuff ----------------------------------------------- /*! \defgroup FLEXT_S_LOCK Global system locking @{ */ #if FLEXT_SYS == FLEXT_SYS_PD #if PD_MINOR_VERSION >= 38 || (PD_MINOR_VERSION >= 37 && defined(PD_DEVEL_VERSION)) static void Lock() { sys_lock(); } static void Unlock() { sys_unlock(); } #else // no system locking for old PD versions static void Lock() {} static void Unlock() {} #endif #elif FLEXT_SYS == FLEXT_SYS_MAX // Max 4.2 upwards! static void Lock() { critical_enter(0); } static void Unlock() { critical_exit(0); } #else #error #endif //! @} FLEXT_S_LOCK /*! \defgroup FLEXT_S_THREAD Flext thread handling @{ */ //! Check if current thread is registered to be a secondary thread #ifdef FLEXT_THREADS static bool IsThreadRegistered(); #else static bool IsThreadRegistered() { return false; } #endif #ifdef FLEXT_THREADS //! thread type # if FLEXT_THREADS == FLEXT_THR_MP typedef MPTaskID thrid_t; # elif FLEXT_THREADS == FLEXT_THR_POSIX typedef pthread_t thrid_t; # elif FLEXT_THREADS == FLEXT_THR_WIN32 typedef DWORD thrid_t; # else # error Threading model not supported # endif /*! \brief Get current thread id */ static thrid_t GetThreadId() { #if FLEXT_THREADS == FLEXT_THR_POSIX return pthread_self(); #elif FLEXT_THREADS == FLEXT_THR_MP return MPCurrentTaskID(); #elif FLEXT_THREADS == FLEXT_THR_WIN32 return GetCurrentThreadId(); #else #error #endif } /*! \brief Get system thread id */ static thrid_t GetSysThreadId() { return thrid; } //! Check if current thread should terminate static bool ShouldExit(); //! Check if current thread is the realtime system's thread static bool IsThread(thrid_t t,thrid_t ref = GetThreadId()) { #if FLEXT_THREADS == FLEXT_THR_POSIX return pthread_equal(ref,t) != 0; #else return ref == t; #endif } /*! \brief Thread parameters \internal */ class FLEXT_SHARE thr_params: public flext_root { public: thr_params(int n = 1): cl(NULL),var(new _data[n]) {} ~thr_params() { delete[] var; } void set_any(const t_symbol *s,int argc,const t_atom *argv) { var[0]._any = new AtomAnything(s,argc,argv); } void set_list(int argc,const t_atom *argv) { var[0]._list = new AtomList(argc,argv); } FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_base)) *cl; union _data { bool _bool; float _float; int _int; t_symptr _t_symptr; AtomAnything *_any; AtomList *_list; void *_ext; } *var; }; protected: static thrid_t thrhelpid; static thrid_t thrmsgid; static void ThrHelper(void *); //! the system's thread id static thrid_t thrid; // the system thread private: static bool StartHelper(); // used in flext::Setup() public: /*! \brief Yield to other threads \remark A call to this is only needed for systems with cooperative multitasking like MacOS<=9 */ static void ThrYield() { #if FLEXT_THREADS == FLEXT_THR_POSIX // for a preemptive system this should do nothing sched_yield(); #elif FLEXT_THREADS == FLEXT_THR_MP MPYield(); #elif FLEXT_THREADS == FLEXT_THR_WIN32 SwitchToThread(); #else #error #endif } /*! \brief Query whether task is preemptive */ static bool IsThreadPreemptive(thrid_t t = GetThreadId()) { #if FLEXT_THREADS == FLEXT_THR_POSIX || FLEXT_THREADS == FLEXT_THR_WIN32 return true; #elif FLEXT_THREADS == FLEXT_THR_MP return MPTaskIsPreemptive(t); #else #error #endif } /*! \brief Increase/Decrease priority of a thread */ static bool RelPriority(int dp,thrid_t ref = GetSysThreadId(),thrid_t thr = GetThreadId()); /*! \brief Get priority of a thread */ static int GetPriority(thrid_t thr = GetThreadId()); /*! \brief Set priority of a thread */ static bool SetPriority(int p,thrid_t thr = GetThreadId()); /*! \brief Thread mutex \sa pthreads documentation */ class FLEXT_SHARE ThrMutex: public flext_root #if FLEXT_THREADS == FLEXT_THR_POSIX { public: //! Construct thread mutex ThrMutex() { pthread_mutex_init(&mutex,NULL); } //! Destroy thread mutex ~ThrMutex() { pthread_mutex_destroy(&mutex); } //! Lock thread mutex bool Lock() { return pthread_mutex_lock(&mutex) == 0; } /*! Wait to lock thread mutex. \todo Implement! */ // bool WaitForLock(double tm) { return pthread_mutex_lock(&mutex) == 0; } //! Try to lock, but don't wait bool TryLock() { return pthread_mutex_trylock(&mutex) == 0; } //! Unlock thread mutex bool Unlock() { return pthread_mutex_unlock(&mutex) == 0; } protected: pthread_mutex_t mutex; // int cnt; }; #elif FLEXT_THREADS == FLEXT_THR_WIN32 { public: //! Construct thread mutex ThrMutex() { ::InitializeCriticalSection(&mutex); } //! Destroy thread mutex ~ThrMutex() { ::DeleteCriticalSection(&mutex); } //! Lock thread mutex bool Lock() { ::EnterCriticalSection(&mutex); return true; } /*! Wait to lock thread mutex. \todo Implement! */ // bool WaitForLock(double tm) { return pthread_mutex_lock(&mutex) == 0; } //! Try to lock, but don't wait bool TryLock() { return ::TryEnterCriticalSection(&mutex) != 0; } //! Unlock thread mutex bool Unlock() { ::LeaveCriticalSection(&mutex); return true; } protected: CRITICAL_SECTION mutex; }; #elif FLEXT_THREADS == FLEXT_THR_MP { public: //! Construct thread mutex ThrMutex() { MPCreateCriticalRegion(&crit); } //! Destroy thread mutex ~ThrMutex() { MPDeleteCriticalRegion(crit); } //! Lock thread mutex bool Lock() { return MPEnterCriticalRegion(crit,kDurationForever) == noErr; } //! Wait to lock thread mutex // bool WaitForLock(double tm) { return MPEnterCriticalRegion(crit,tm*kDurationMicrosecond*1.e6) == noErr; } //! Try to lock, but don't wait bool TryLock() { return MPEnterCriticalRegion(crit,kDurationImmediate) == noErr; } //! Unlock thread mutex bool Unlock() { return MPExitCriticalRegion(crit) == noErr; } protected: MPCriticalRegionID crit; }; #else #error "Not implemented" #endif /*! \brief Thread conditional \sa pthreads documentation */ class FLEXT_SHARE ThrCond #if FLEXT_THREADS == FLEXT_THR_POSIX :public ThrMutex { public: //! Construct thread conditional ThrCond() { pthread_cond_init(&cond,NULL); } //! Destroy thread conditional ~ThrCond() { pthread_cond_destroy(&cond); } //! Wait for condition bool Wait(); /*! Wait for condition (for a certain time). \param ftime Wait time in seconds \ret true = signalled, false = timed out \remark If ftime = 0 this may suck away your cpu if used in a signalled loop. \remark The time resolution of the implementation is required to be at least ms. */ bool TimedWait(double ftime); //! Signal condition bool Signal() { return pthread_cond_signal(&cond) == 0; } protected: pthread_cond_t cond; }; #elif FLEXT_THREADS == FLEXT_THR_WIN32 { public: //! Construct thread conditional ThrCond() { cond = CreateEvent(NULL,FALSE,FALSE,NULL); } //! Destroy thread conditional ~ThrCond() { CloseHandle(cond); } //! Wait for condition bool Wait() { return WaitForSingleObject(cond,INFINITE) == WAIT_OBJECT_0; } /*! Wait for condition (for a certain time). \param ftime Wait time in seconds \ret true = signalled, false = timed out \remark If ftime = 0 this may suck away your cpu if used in a signalled loop. \remark The time resolution of the implementation is required to be at least ms. */ bool TimedWait(double ftime) { return WaitForSingleObject(cond,(LONG)(ftime*1000)) == WAIT_OBJECT_0; } //! Signal condition bool Signal() { return SetEvent(cond) != 0; } protected: HANDLE cond; }; #elif FLEXT_THREADS == FLEXT_THR_MP { public: //! Construct thread conditional ThrCond() { MPCreateEvent(&ev); } //! Destroy thread conditional ~ThrCond() { MPDeleteEvent(ev); } //! Wait for condition bool Wait() { return MPWaitForEvent(ev,NULL,kDurationForever) == noErr; } /*! \brief Wait for condition (for a certain time). \param time Wait time in seconds */ bool TimedWait(double tm) { return MPWaitForEvent(ev,NULL,tm*kDurationMicrosecond*1.e6) == noErr; } //! Signal condition bool Signal() { return MPSetEvent(ev,1) == noErr; } // one bit needs to be set at least protected: MPEventID ev; }; #else #error "Not implemented" #endif protected: /*! \brief Add current thread to list of active threads. \note Calls RegisterThread automatically \return true on success \internal */ static bool PushThread(); /*! \brief Remove current thread from list of active threads. \note Calls UnregisterThread automatically \internal */ static void PopThread(); public: /*! \brief Launch a thread. \param meth Thread function \param params Parameters to pass to the thread, may be NULL if not needed. \return Thread id on success, NULL on failure */ static bool LaunchThread(void (*meth)(thr_params *p),thr_params *params = NULL); /*! \brief Terminate a thread. \param meth Thread function \param params Parameters to pass to the thread, may be NULL if not needed. \return True if at least one matching thread has been found. \remark Terminates all running threads with matching meth and params. \note Function doesn NOT wait for termination */ static bool StopThread(void (*meth)(thr_params *p),thr_params *params = NULL,bool wait = false); //! \brief Register current thread to be allowed to execute flext functions. static void RegisterThread(thrid_t id = GetThreadId()); //! \brief Unregister current thread static void UnregisterThread(thrid_t id = GetThreadId()); #endif // FLEXT_THREADS //! @} FLEXT_S_THREAD public: // --- timer stuff ----------------------------------------------- /*! \defgroup FLEXT_S_TIMER Flext timer handling @{ \remark The clock of the real-time system is used for most of these functions. \remark Since this clock can be synchronized to an external clock (or e.g. the audio card) \remark it may differ from the clock of the operating system */ /*! \brief Get time since real-time system startup. \note This is not the time of the operating system but of the real-time system. \note It may depend on the time source the system is synchronized to (e.g. audio sample rate). */ static double GetTime() { #if FLEXT_SYS == FLEXT_SYS_PD return clock_gettimesince(0)*0.001; #elif FLEXT_SYS == FLEXT_SYS_MAX double tm; clock_getftime(&tm); return tm*0.001; #else #error Not implemented #endif } /*! \brief Get time granularity of the GetTime function. \note This can be zero if not determined. */ static double GetTimeGrain() { #if FLEXT_SYS == FLEXT_SYS_PD return 0; #elif FLEXT_SYS == FLEXT_SYS_MAX return 0.001; #else #error Not implemented #endif } /*! \brief Get operating system time since flext startup. */ static double GetOSTime(); /*! \brief Sleep for an amount of time. \remark The OS clock is used for that. \note Clearly in a real-time system this should only be used in a detached thread. */ static void Sleep(double s); /*! \brief Class encapsulating a timer with callback functionality. This class can either be used with FLEXT_ADDTIMER or used as a base class with an overloaded virtual Work function. */ class FLEXT_SHARE Timer: public flext_root { public: Timer(bool queued = false); virtual ~Timer(); //! Set timer callback function. void SetCallback(void (*cb)(void *data)) { clss = NULL,cback = cb; } //! Set timer callback function (with class pointer). void SetCallback(FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_base)) &th,bool (*cb)(FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_base)) *th,void *data)) { clss = &th,cback = (void (*)(void *))cb; } //! Clear timer. bool Reset(); //! Trigger a one shot at an absolute time. bool At(double time,void *data = NULL,bool dopast = true); //! Trigger a one shot interval. bool Delay(double time,void *data = NULL); //! Trigger a periodic interval. bool Periodic(double time,void *data = NULL); //! Trigger immediately. bool Now(void *data = NULL) { return Delay(0,data); } //! Worker function, called on every timer event. virtual void Work(); protected: static void callback(Timer *tmr); #if FLEXT_SYS == FLEXT_SYS_PD t_clock *clk; #elif FLEXT_SYS == FLEXT_SYS_MAX static void queuefun(Timer *tmr); t_clock *clk; t_qelem *qelem; #else #error Not implemented #endif const bool queued; void (*cback)(void *data); FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_base)) *clss; void *userdata; double period; }; //! @} FLEXT_S_TIMER //! Check if we are in DSP time static bool InDSP() { return indsp; } // --- SIMD functionality ----------------------------------------------- /*! \defgroup FLEXT_S_SIMD Cross platform SIMD support for modern CPUs @{ */ enum simd_type { simd_none = 0, simd_mmx = 0x01, simd_3dnow = 0x02, simd_sse = 0x04, simd_sse2 = 0x08, simd_altivec = 0x10 }; /*! Check for SIMD capabilities of the CPU */ static unsigned long GetSIMDCapabilities(); static void MulSamples(t_sample *dst,const t_sample *src,t_sample mul,int cnt); static void MulSamples(t_sample *dst,const t_sample *src,const t_sample *mul,int cnt); static void AddSamples(t_sample *dst,const t_sample *src,t_sample add,int cnt); static void AddSamples(t_sample *dst,const t_sample *src,const t_sample *add,int cnt); static void ScaleSamples(t_sample *dst,const t_sample *src,t_sample mul,t_sample add,int cnt); static void ScaleSamples(t_sample *dst,const t_sample *src,t_sample mul,const t_sample *add,int cnt); static void ScaleSamples(t_sample *dst,const t_sample *src,const t_sample *mul,const t_sample *add,int cnt); //! @} FLEXT_S_SIMD //! @} FLEXT_SUPPORT protected: #ifdef __MRC__ friend class flext_obj; #endif static void Setup(); static bool chktilde(const char *objname); static unsigned long simdcaps; static const t_symbol *sym_attributes; static const t_symbol *sym_methods; #if FLEXT_SYS == FLEXT_SYS_MAX static const t_symbol *sym_buffer; static const t_symbol *sym_size; static const t_symbol *sym_dirty; #endif //! flag if we are within DSP static bool indsp; }; // gcc doesn't like these to be included into the flext class (even if static) inline bool operator ==(const t_atom &a,const t_atom &b) { return flext::CmpAtom(a,b) == 0; } inline bool operator !=(const t_atom &a,const t_atom &b) { return flext::CmpAtom(a,b) != 0; } inline bool operator <(const t_atom &a,const t_atom &b) { return flext::CmpAtom(a,b) < 0; } inline bool operator <=(const t_atom &a,const t_atom &b) { return flext::CmpAtom(a,b) <= 0; } inline bool operator >(const t_atom &a,const t_atom &b) { return flext::CmpAtom(a,b) > 0; } inline bool operator >=(const t_atom &a,const t_atom &b) { return flext::CmpAtom(a,b) >= 0; } //! @} // FLEXT_SUPPORT #include "flpopns.h" #endif flext-0-6-3/source/flthr.cpp000066400000000000000000000473711446466241400160120ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flthr.cpp \brief Implementation of the flext thread functionality. */ #ifndef __FLEXT_THR_CPP #define __FLEXT_THR_CPP #include "flext.h" #ifdef FLEXT_THREADS // maximum wait time for threads to finish (in ms) #define MAXIMUMWAIT 100 #include "flinternal.h" #include "flcontainers.h" #include #include #if FLEXT_OSAPI == FLEXT_OSAPI_MAC_MACH || FLEXT_OSAPI == FLEXT_OSAPI_UNIX_POSIX || FLEXT_OSAPI == FLEXT_OSAPI_WIN_POSIX #include #include #elif FLEXT_OS == FLEXT_OS_WIN #include #endif #if FLEXT_THREADS == FLEXT_THR_WIN32 && WINVER < 0x0500 #error WIN32 threads need Windows SDK version >= 0x500 #endif #include #include "flpushns.h" //! Thread id of system thread - will be initialized in flext::Setup FLEXT_TEMPIMPL(FLEXT_TEMPINST(FLEXT_CLASSDEF(flext))::thrid_t FLEXT_CLASSDEF(flext))::thrid; //! Thread id of helper thread - will be initialized in flext::Setup FLEXT_TEMPIMPL(FLEXT_TEMPINST(FLEXT_CLASSDEF(flext))::thrid_t FLEXT_CLASSDEF(flext))::thrhelpid; //! \brief This represents an entry to the list of active method threads class thr_entry : public flext , public LifoCell { public: void Set(void (*m)(thr_params *),thr_params *p,thrid_t id = GetThreadId()) { th = p?p->cl:NULL; meth = m; params = p; thrid = id; shouldexit = false; #if FLEXT_THREADS == FLEXT_THR_MP weight = 100; // MP default weight #endif } //! \brief Check if this class represents the current thread bool Is(thrid_t id = GetThreadId()) const { return IsThread(thrid,id); } FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_base)) *This() const { return th; } thrid_t Id() const { return thrid; } FLEXT_TEMPINST(FLEXT_CLASSDEF(flext_base)) *th; void (*meth)(thr_params *); thr_params *params; thrid_t thrid; bool shouldexit; #if FLEXT_THREADS == FLEXT_THR_MP int weight; #endif }; template class ThrFinder: public T { public: ~ThrFinder() { thr_entry *e; while((e = Pop()) != NULL) delete e; } void Push(thr_entry *e) { T::Push(e); } thr_entry *Pop() { return T::Pop(); } thr_entry *Find(flext::thrid_t id,bool pop = false) { TypedLifo qutmp; thr_entry *fnd; while((fnd = Pop()) && !fnd->Is(id)) qutmp.Push(fnd); // put back entries for(thr_entry *ti; (ti = qutmp.Pop()) != NULL; ) Push(ti); if(fnd && !pop) Push(fnd); return fnd; } }; FLEXT_TEMPLATE struct ThrRegistry { typedef ThrFinder< PooledLifo > RegPooledLifo; typedef ThrFinder< TypedLifo > RegFinder; static RegPooledLifo pending; static RegFinder active,stopped; }; FLEXT_TEMPIMPL(FLEXT_TEMPINST(ThrRegistry)::RegPooledLifo ThrRegistry)::pending; FLEXT_TEMPIMPL(FLEXT_TEMPINST(ThrRegistry)::RegFinder ThrRegistry)::active; FLEXT_TEMPIMPL(FLEXT_TEMPINST(ThrRegistry)::RegFinder ThrRegistry)::stopped; class ThrId : public flext { public: ThrId(const thrid_t &_id): id(_id) {} thrid_t id; bool operator <(const ThrId &tid) const { if(sizeof(id) == sizeof(unsigned)) return (unsigned *)&id < (unsigned *)&tid; else return memcmp(&id,&tid,sizeof(id)) < 0; } }; FLEXT_TEMPLATE struct ThrVars { // this should _definitely_ be a hashmap.... // \TODO above all it should be populated immediately, otherwise it could easily happen // that the passing on to the set happens too late! We need that lockfree set! static std::set regthreads; //! Registry lock static flext::ThrMutex *thrregmtx; //! Helper thread conditional static flext::ThrCond *thrhelpcond; static bool initialized; }; FLEXT_TEMPIMPL(std::set ThrVars)::regthreads; FLEXT_TEMPIMPL(flext::ThrMutex *ThrVars)::thrregmtx = NULL; FLEXT_TEMPIMPL(flext::ThrCond *ThrVars)::thrhelpcond = NULL; FLEXT_TEMPIMPL(bool ThrVars)::initialized = false; FLEXT_TEMPLATE void LaunchHelper(thr_entry *e) { e->thrid = flext::GetThreadId(); flext::RegisterThread(e->thrid); e->meth(e->params); flext::UnregisterThread(e->thrid); } //! Start helper thread FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::StartHelper() { bool ok = false; FLEXT_TEMPINST(ThrVars)::initialized = false; FLEXT_TEMPINST(ThrVars)::thrregmtx = new ThrMutex; #if FLEXT_THREADS == FLEXT_THR_POSIX pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); pthread_t tmp; ok = pthread_create (&tmp,&attr,(void *(*)(void *))ThrHelper,NULL) == 0; #elif FLEXT_THREADS == FLEXT_THR_MP if(!MPLibraryIsLoaded()) error("Thread library is not loaded"); else { MPTaskID tmp; OSStatus ret = MPCreateTask((TaskProc)ThrHelper,NULL,0,0,0,0,0,&tmp); ok = ret == noErr; } #elif FLEXT_THREADS == FLEXT_THR_WIN32 ok = _beginthread(ThrHelper,0,NULL) >= 0; #else #error #endif if(!ok) error("flext - Could not launch helper thread!"); else { // now we have to wait for thread helper to initialize while(!FLEXT_TEMPINST(ThrVars)::initialized) Sleep(0.001); // we are ready for threading now! } #if FLEXT_THREADS == FLEXT_THR_POSIX pthread_attr_destroy(&attr); #endif return ok; } //! Static helper thread function FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ThrHelper(void *) { thrhelpid = GetThreadId(); #if FLEXT_THREADS == FLEXT_THR_POSIX // set prototype thread attributes pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); #endif // set thread priority one point below normal // so thread construction won't disturb real-time audio RelPriority(-1); FLEXT_TEMPINST(ThrVars)::thrhelpcond = new ThrCond; FLEXT_TEMPINST(ThrVars)::initialized = true; // helper loop for(;;) { FLEXT_TEMPINST(ThrVars)::thrhelpcond->Wait(); // start all inactive threads thr_entry *ti; while((ti = FLEXT_TEMPINST(ThrRegistry)::pending.Pop()) != NULL) { bool ok; #if FLEXT_THREADS == FLEXT_THR_POSIX thrid_t dummy; ok = pthread_create (&dummy,&attr,(void *(*)(void *))FLEXT_TEMPINST(LaunchHelper),ti) == 0; #elif FLEXT_THREADS == FLEXT_THR_MP thrid_t dummy; ok = MPCreateTask((TaskProc)FLEXT_TEMPINST(LaunchHelper),ti,0,0,0,0,0,&dummy) == noErr; #elif FLEXT_THREADS == FLEXT_THR_WIN32 ok = _beginthread((void (*)(void *))FLEXT_TEMPINST(LaunchHelper),0,ti) >= 0; #else #error #endif if(!ok) { error("flext - Could not launch thread!"); FLEXT_TEMPINST(ThrRegistry)::pending.Free(ti); ti = NULL; } else // insert into queue of active threads FLEXT_TEMPINST(ThrRegistry)::active.Push(ti); } } FLEXT_ASSERT(false); /* // Never reached! delete thrhelpcond; thrhelpcond = NULL; #if FLEXT_THREADS == FLEXT_THR_POSIX pthread_attr_destroy(&attr); #endif */ } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::LaunchThread(void (*meth)(thr_params *p),thr_params *p) { FLEXT_ASSERT(FLEXT_TEMPINST(ThrVars)::thrhelpcond); // make an entry into thread list thr_entry *e = FLEXT_TEMPINST(ThrRegistry)::pending.New(); e->Set(meth,p); FLEXT_TEMPINST(ThrRegistry)::pending.Push(e); // signal thread helper FLEXT_TEMPINST(ThrVars)::thrhelpcond->Signal(); return true; } FLEXT_TEMPLATE bool waitforstopped(TypedLifo &qufnd,float wait = 0) { TypedLifo qutmp; double until; if(wait) until = flext::GetOSTime()+wait; for(;;) { thr_entry *fnd = qufnd.Pop(); if(!fnd) break; // no more entries -> done! thr_entry *ti; // search for entry while((ti = FLEXT_TEMPINST(ThrRegistry)::stopped.Pop()) != NULL && ti != fnd) qutmp.Push(ti); // put back entries while((ti = qutmp.Pop()) != NULL) FLEXT_TEMPINST(ThrRegistry)::stopped.Push(ti); if(ti) { // still in ThrRegistry::stopped queue qufnd.Push(fnd); // yield to other threads flext::ThrYield(); if(wait && flext::GetOSTime() > until) // not successful -> remaining thread are still in qufnd queue return false; } } return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::StopThread(void (*meth)(thr_params *p),thr_params *p,bool wait) { FLEXT_ASSERT(FLEXT_TEMPINST(ThrVars)::thrhelpcond); TypedLifo qutmp; thr_entry *ti; // first search pending queue // -------------------------- { bool found = false; while((ti = FLEXT_TEMPINST(ThrRegistry)::pending.Pop()) != NULL) if(ti->meth == meth && ti->params == p) { // found -> thread hasn't started -> just delete FLEXT_TEMPINST(ThrRegistry)::pending.Free(ti); found = true; } else qutmp.Push(ti); // put back into pending queue (order doesn't matter) while((ti = qutmp.Pop()) != NULL) FLEXT_TEMPINST(ThrRegistry)::pending.Push(ti); if(found) return true; } // now search active queue // ----------------------- TypedLifo qufnd; while((ti = FLEXT_TEMPINST(ThrRegistry)::active.Pop()) != NULL) if(ti->meth == meth && ti->params == p) { FLEXT_TEMPINST(ThrRegistry)::stopped.Push(ti); FLEXT_TEMPINST(ThrVars)::thrhelpcond->Signal(); qufnd.Push(ti); } else qutmp.Push(ti); // put back into pending queue (order doesn't matter) while((ti = qutmp.Pop()) != NULL) FLEXT_TEMPINST(ThrRegistry)::active.Push(ti); // wakeup helper thread FLEXT_TEMPINST(ThrVars)::thrhelpcond->Signal(); // now wait for entries in qufnd to have vanished from ThrRegistry::stopped if(wait) return FLEXT_TEMPINST(waitforstopped)(qufnd); else return !qufnd.Avail(); } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::ShouldExit() { return FLEXT_TEMPINST(ThrRegistry)::stopped.Find(GetThreadId()) != NULL; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::PushThread() { // set priority of newly created thread one point below the system thread's RelPriority(-1); RegisterThread(); return true; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::PopThread() { thrid_t id = GetThreadId(); UnregisterThread(id); thr_entry *fnd = FLEXT_TEMPINST(ThrRegistry)::stopped.Find(id,true); if(!fnd) fnd = FLEXT_TEMPINST(ThrRegistry)::active.Find(id,true); if(fnd) FLEXT_TEMPINST(ThrRegistry)::pending.Free(fnd); #ifdef FLEXT_DEBUG else post("flext - INTERNAL ERROR: Thread not found!"); #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::RegisterThread(thrid_t id) { #if 1 FLEXT_ASSERT(FLEXT_TEMPINST(ThrVars)::thrregmtx); FLEXT_TEMPINST(ThrVars)::thrregmtx->Lock(); FLEXT_TEMPINST(ThrVars)::regthreads.insert(id); FLEXT_TEMPINST(ThrVars)::thrregmtx->Unlock(); #else regqueue.Push(new ThrIdCell(id)); #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::UnregisterThread(thrid_t id) { #if 1 FLEXT_ASSERT(FLEXT_TEMPINST(ThrVars)::thrregmtx); FLEXT_TEMPINST(ThrVars)::thrregmtx->Lock(); FLEXT_TEMPINST(ThrVars)::regthreads.erase(id); FLEXT_TEMPINST(ThrVars)::thrregmtx->Unlock(); #else unregqueue.Push(new ThrIdCell(id)); #endif } #if 0 FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ThreadRegistryWorker() { ThrIdCell *pid; while((pid = regqueue.Pop()) != NULL) { regthreads.insert(pid->id); delete pid; } while((pid = unregqueue.Pop()) != NULL) { regthreads.erase(pid->id); delete pid; } } #endif FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::IsThreadRegistered() { FLEXT_ASSERT(FLEXT_TEMPINST(ThrVars)::thrregmtx); FLEXT_TEMPINST(ThrVars)::thrregmtx->Lock(); bool fnd = FLEXT_TEMPINST(ThrVars)::regthreads.find(GetThreadId()) != FLEXT_TEMPINST(ThrVars)::regthreads.end(); FLEXT_TEMPINST(ThrVars)::thrregmtx->Unlock(); return fnd; } //! Terminate all object threads FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::StopThreads() { FLEXT_ASSERT(FLEXT_TEMPINST(ThrVars)::thrhelpcond); TypedLifo qutmp; thr_entry *ti; // first search pending queue // -------------------------- while((ti = FLEXT_TEMPINST(ThrRegistry)::pending.Pop()) != NULL) if(ti->This() == this) // found -> thread hasn't started -> just delete FLEXT_TEMPINST(ThrRegistry)::pending.Free(ti); else qutmp.Push(ti); // put back into pending queue (order doesn't matter) while((ti = qutmp.Pop()) != NULL) FLEXT_TEMPINST(ThrRegistry)::pending.Push(ti); // now search active queue // ----------------------- TypedLifo qufnd; while((ti = FLEXT_TEMPINST(ThrRegistry)::active.Pop()) != NULL) if(ti->This() == this) { FLEXT_TEMPINST(ThrRegistry)::stopped.Push(ti); FLEXT_TEMPINST(ThrVars)::thrhelpcond->Signal(); qufnd.Push(ti); } else qutmp.Push(ti); // put back into pending queue (order doesn't matter) while((ti = qutmp.Pop()) != NULL) FLEXT_TEMPINST(ThrRegistry)::active.Push(ti); // wakeup helper thread FLEXT_TEMPINST(ThrVars)::thrhelpcond->Signal(); // now wait for entries in qufnd to have vanished from ThrRegistry::stopped if(!FLEXT_TEMPINST(waitforstopped)(qufnd,MAXIMUMWAIT*0.001f)) { #ifdef FLEXT_DEBUG post("flext - doing hard thread termination"); #endif // timeout -> hard termination while((ti = qufnd.Pop()) != NULL) { #if FLEXT_THREADS == FLEXT_THR_POSIX if(pthread_cancel(ti->thrid)) post("%s - Thread could not be terminated!",thisName()); #elif FLEXT_THREADS == FLEXT_THR_MP MPTerminateTask(ti->thrid,0); // here, we should use a task queue to check whether the task has really terminated!! #elif FLEXT_THREADS == FLEXT_THR_WIN32 // can't use the c library function _endthread.. memory leaks will occur HANDLE hnd = OpenThread(THREAD_ALL_ACCESS,TRUE,ti->thrid); TerminateThread(hnd,0); #else # error Not implemented #endif FLEXT_TEMPINST(ThrRegistry)::pending.Free(ti); } return false; } else return true; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::RelPriority(int dp,thrid_t ref,thrid_t id) { #if FLEXT_THREADS == FLEXT_THR_POSIX sched_param parm; int policy; if(pthread_getschedparam(ref,&policy,&parm) < 0) { # ifdef FLEXT_DEBUG post("flext - failed to get thread priority"); # endif return false; } else { parm.sched_priority += dp; // MSVC++ 6 produces wrong code with the following lines!!! // int schmin = sched_get_priority_min(policy); // int schmax = sched_get_priority_max(policy); if(parm.sched_priority < sched_get_priority_min(policy)) { # ifdef FLEXT_DEBUG post("flext - minimum thread priority reached"); # endif parm.sched_priority = sched_get_priority_min(policy); } else if(parm.sched_priority > sched_get_priority_max(policy)) { # ifdef FLEXT_DEBUG post("flext - maximum thread priority reached"); # endif parm.sched_priority = sched_get_priority_max(policy); } if(pthread_setschedparam(id,policy,&parm) < 0) { # ifdef FLEXT_DEBUG post("flext - failed to change thread priority"); # endif return false; } } return true; #elif FLEXT_THREADS == FLEXT_THR_WIN32 HANDLE href = OpenThread(THREAD_ALL_ACCESS,TRUE,ref); HANDLE hid = OpenThread(THREAD_ALL_ACCESS,TRUE,id); int pr = GetThreadPriority(href); if(pr == THREAD_PRIORITY_ERROR_RETURN) { # ifdef FLEXT_DEBUG post("flext - failed to get thread priority"); # endif return false; } pr += dp; if(pr < THREAD_PRIORITY_IDLE) { # ifdef FLEXT_DEBUG post("flext - minimum thread priority reached"); # endif pr = THREAD_PRIORITY_IDLE; } else if(pr > THREAD_PRIORITY_TIME_CRITICAL) { # ifdef FLEXT_DEBUG post("flext - maximum thread priority reached"); # endif pr = THREAD_PRIORITY_TIME_CRITICAL; } if(SetThreadPriority(hid,pr) == 0) { # ifdef FLEXT_DEBUG post("flext - failed to change thread priority"); # endif return false; } return true; #elif FLEXT_THREADS == FLEXT_THR_MP thr_entry *ti = FLEXT_TEMPINST(ThrRegistry)::pending.Find(id); if(!ti) ti = FLEXT_TEMPINST(ThrRegistry)::active.Find(id); if(ti) { // thread found in list int w = GetPriority(id); if(dp < 0) w /= 1<<(-dp); else w *= 1< 10000) { # ifdef FLEXT_DEBUG post("flext - maximum thread priority reached"); # endif w = 10000; } ti->weight = w; return MPSetTaskWeight(id,w) == noErr; } else return false; #else # error #endif } FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::GetPriority(thrid_t id) { #if FLEXT_THREADS == FLEXT_THR_POSIX sched_param parm; int policy; if(pthread_getschedparam(id,&policy,&parm) < 0) { # ifdef FLEXT_DEBUG post("flext - failed to get parms"); # endif return -1; } return parm.sched_priority; #elif FLEXT_THREADS == FLEXT_THR_WIN32 HANDLE hid = OpenThread(THREAD_ALL_ACCESS,TRUE,id); int pr = GetThreadPriority(hid); if(pr == THREAD_PRIORITY_ERROR_RETURN) { # ifdef FLEXT_DEBUG post("flext - failed to get thread priority"); # endif return -1; } return pr; #elif FLEXT_THREADS == FLEXT_THR_MP thr_entry *ti = FLEXT_TEMPINST(ThrRegistry)::pending.Find(id); if(!ti) ti = FLEXT_TEMPINST(ThrRegistry)::active.Find(id); return ti?ti->weight:-1; #else # error #endif } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::SetPriority(int p,thrid_t id) { #if FLEXT_THREADS == FLEXT_THR_POSIX sched_param parm; int policy; if(pthread_getschedparam(id,&policy,&parm) < 0) { # ifdef FLEXT_DEBUG post("flext - failed to get parms"); # endif return false; } else { parm.sched_priority = p; if(pthread_setschedparam(id,policy,&parm) < 0) { # ifdef FLEXT_DEBUG post("flext - failed to change priority"); # endif return false; } } return true; #elif FLEXT_THREADS == FLEXT_THR_WIN32 HANDLE hid = OpenThread(THREAD_ALL_ACCESS,TRUE,id); if(SetThreadPriority(hid,p) == 0) { # ifdef FLEXT_DEBUG post("flext - failed to change thread priority"); # endif return false; } return true; #elif FLEXT_THREADS == FLEXT_THR_MP thr_entry *ti = FLEXT_TEMPINST(ThrRegistry)::pending.Find(id); if(!ti) ti = FLEXT_TEMPINST(ThrRegistry)::active.Find(id); return ti && MPSetTaskWeight(id,ti->weight = p) == noErr; #else # error #endif } #if FLEXT_THREADS == FLEXT_THR_POSIX FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::ThrCond::Wait() { this->Lock(); // use this-> to avoid wrong function invocation (global Unlock) bool ret = pthread_cond_wait(&cond,&this->mutex) == 0; this->Unlock(); // use this-> to avoid wrong function invocation (global Unlock) return ret; } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::ThrCond::TimedWait(double ftm) { timespec tm; #if FLEXT_OS == FLEXT_OS_WIN && FLEXT_OSAPI == FLEXT_OSAPI_WIN_NATIVE # ifdef _MSC_VER _timeb tmb; _ftime(&tmb); # else timeb tmb; ftime(&tmb); # endif tm.tv_nsec = tmb.millitm*1000000; tm.tv_sec = (long)tmb.time; #else // POSIX # if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) clock_gettime(CLOCK_REALTIME,&tm); # else struct timeval tp; gettimeofday(&tp, NULL); tm.tv_nsec = tp.tv_usec*1000; tm.tv_sec = tp.tv_sec; # endif #endif tm.tv_nsec += (long)((ftm-(long)ftm)*1.e9); long nns = tm.tv_nsec%1000000000; tm.tv_sec += (long)ftm+(tm.tv_nsec-nns)/1000000000; tm.tv_nsec = nns; this->Lock(); // use this-> to avoid wrong function invocation (global Unlock) bool ret = pthread_cond_timedwait(&cond,&this->mutex,&tm) == 0; this->Unlock(); // use this-> to avoid wrong function invocation (global Unlock) return ret; } #endif #include "flpopns.h" #endif // FLEXT_THREADS #endif // __FLEXT_THR_CPP flext-0-6-3/source/fltimer.cpp000066400000000000000000000175371446466241400163360ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file fltimer.cpp \brief flext timer functions and classes */ #ifndef __FLEXT_TIMER_CPP #define __FLEXT_TIMER_CPP #include "flext.h" #if FLEXT_OS == FLEXT_OS_WIN #include #elif FLEXT_OS == FLEXT_OS_LINUX || FLEXT_OS == FLEXT_OS_IRIX || FLEXT_OSAPI == FLEXT_OSAPI_MAC_MACH #include #include #elif FLEXT_OS == FLEXT_OS_MAC #include #include #endif #include "flpushns.h" FLEXT_TEMPLATE double getstarttime(); FLEXT_TEMPLATE struct TimerVars { #if FLEXT_OS == FLEXT_OS_WIN static double perffrq; #endif static double starttime; }; #if FLEXT_OS == FLEXT_OS_WIN FLEXT_TEMPIMPL(double TimerVars)::perffrq = 0; #endif FLEXT_TEMPIMPL(double TimerVars)::starttime = FLEXT_TEMPINST(getstarttime)(); FLEXT_TEMPLATE double getstarttime() { #if FLEXT_OS == FLEXT_OS_WIN LARGE_INTEGER frq; if(QueryPerformanceFrequency(&frq)) FLEXT_TEMPINST(TimerVars)::perffrq = (double)frq.QuadPart; #endif FLEXT_TEMPINST(TimerVars)::starttime = 0; return flext::GetOSTime(); } FLEXT_TEMPIMPL(double FLEXT_CLASSDEF(flext))::GetOSTime() { double tm; #if FLEXT_OS == FLEXT_OS_WIN LARGE_INTEGER cnt; if(FLEXT_TEMPINST(TimerVars)::perffrq && QueryPerformanceCounter(&cnt)) tm = cnt.QuadPart/FLEXT_TEMPINST(TimerVars)::perffrq; else { SYSTEMTIME systm; FILETIME fltm; GetSystemTime(&systm); SystemTimeToFileTime(&systm,&fltm); tm = ((LARGE_INTEGER *)&fltm)->QuadPart*1.e-7; } #elif FLEXT_OS == FLEXT_OS_LINUX || FLEXT_OS == FLEXT_OS_IRIX || FLEXT_OSAPI == FLEXT_OSAPI_MAC_MACH // POSIX timeval tmv; gettimeofday(&tmv,NULL); tm = tmv.tv_sec+tmv.tv_usec*1.e-6; #elif FLEXT_OS == FLEXT_OS_MAC // that's just for OS9 & Carbon! UnsignedWide tick; Microseconds(&tick); tm = (tick.hi*((double)(1L<<((sizeof tick.lo)*4))*(double)(1L<<((sizeof tick.lo)*4)))+tick.lo)*1.e-6; #else #error Not implemented #endif return tm-FLEXT_TEMPINST(TimerVars)::starttime; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::Sleep(double s) { if(s <= 0) return; #if FLEXT_OS == FLEXT_OS_WIN #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x400 #if 0 LARGE_INTEGER liDueTime; liDueTime.QuadPart = (LONGLONG)(-1.e7*s); // Create a waitable timer. HANDLE hTimer = CreateWaitableTimer(NULL,TRUE,NULL); if(hTimer) { if(SetWaitableTimer(hTimer,&liDueTime,0,NULL,NULL,0)) // Wait for the timer. WaitForSingleObject(hTimer,INFINITE); // != WAIT_OBJECT_0) else ::Sleep((long)(s*1000.)); CloseHandle(hTimer); } else #else LARGE_INTEGER cnt; if(FLEXT_TEMPINST(TimerVars)::perffrq && QueryPerformanceCounter(&cnt)) { LONGLONG dst = (LONGLONG)(cnt.QuadPart+FLEXT_TEMPINST(TimerVars)::perffrq*s); for(;;) { SwitchToThread(); // while waiting switch to another thread QueryPerformanceCounter(&cnt); if(cnt.QuadPart > dst) break; } } else #endif #endif // last resort.... ::Sleep((long)(s*1000.)); #elif FLEXT_OS == FLEXT_OS_LINUX || FLEXT_OS == FLEXT_OS_IRIX || FLEXT_OSAPI == FLEXT_OSAPI_MAC_MACH // POSIX usleep((long)(s*1000000.)); #elif FLEXT_OS == FLEXT_OS_MAC // that's just for OS9 & Carbon! UnsignedWide tick; Microseconds(&tick); double target = tick.hi*((double)(1L<<((sizeof tick.lo)*4))*(double)(1L<<((sizeof tick.lo)*4)))+tick.lo+s*1.e6; for(;;) { // this is just a loop running until the time has passed - stone age (but we yield at least) Microseconds(&tick); if(target <= tick.hi*((double)(1L<<((sizeof tick.lo)*4))*(double)(1L<<((sizeof tick.lo)*4)))+tick.lo) break; YieldToAnyThread(); // yielding surely reduces the timing precision (but we're civilized) } #else #error Not implemented #endif } /* \param qu determines whether timed messages should be queued (low priority - only when supported by the system). */ FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext))::Timer::Timer(bool qu): queued(qu), clss(NULL),userdata(NULL), period(0) { #if FLEXT_SYS == FLEXT_SYS_PD clk = (t_clock *)clock_new(this,(t_method)callback); #elif FLEXT_SYS == FLEXT_SYS_MAX clk = (t_clock *)clock_new(this,(t_method)callback); if(queued) qelem = (t_qelem *)qelem_new(this,(method)queuefun); #else #error Not implemented #endif } FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext))::Timer::~Timer() { #if FLEXT_SYS == FLEXT_SYS_PD clock_free(clk); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_free(clk); if(queued) ::qelem_free(qelem); #else #error Not implemented #endif } FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::Timer::Reset() { #if FLEXT_SYS == FLEXT_SYS_PD clock_unset(clk); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_unset(clk); if(queued) ::qelem_unset(qelem); #else #error Not implemented #endif return true; } /*! \param tm absolute time (in seconds) \param data user data \param dopast if set events with times lying in the past will be triggered immediately, if not set they are ignored \return true on success */ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::Timer::At(double tm,void *data,bool dopast) { userdata = data; period = 0; #if FLEXT_SYS == FLEXT_SYS_PD const double systm = clock_gettimesince(0); double df = tm*1000.-systm; if(dopast && df < 0) df = 0; if(df >= 0) clock_delay(clk,df); #elif FLEXT_SYS == FLEXT_SYS_MAX const double ms = tm*1000.; double cur; clock_getftime(&cur); if(cur <= ms) clock_fdelay(clk,ms-cur); else if(dopast) // trigger timer is past clock_fdelay(clk,0); #else #error Not implemented #endif return true; } /*! \param tm relative time (in seconds) \param data user data \return true on success */ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::Timer::Delay(double tm,void *data) { userdata = data; period = 0; #if FLEXT_SYS == FLEXT_SYS_PD clock_delay(clk,tm*1000); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_fdelay(clk,tm*1000.); #else #error Not implemented #endif return true; } /*! \param tm relative time between periodic events (in seconds) \param data user data \return true on success \note the first event will be delayed by tm */ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::Timer::Periodic(double tm,void *data) { userdata = data; period = tm; #if FLEXT_SYS == FLEXT_SYS_PD clock_delay(clk,tm*1000.); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_fdelay(clk,tm*1000.); #else #error Not implemented #endif return true; } //! \brief Callback function for system clock. FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::Timer::callback(Timer *tmr) { #if FLEXT_SYS == FLEXT_SYS_MAX if(tmr->queued) qelem_set(tmr->qelem); else #endif tmr->Work(); if(tmr->period) { // reschedule #if FLEXT_SYS == FLEXT_SYS_PD clock_delay(tmr->clk,tmr->period*1000.); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_fdelay(tmr->clk,tmr->period*1000.); #else #error Not implemented #endif } } #if FLEXT_SYS == FLEXT_SYS_MAX /*! \brief Callback function for low priority clock (for queued messages). */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::Timer::queuefun(Timer *tmr) { tmr->Work(); } #endif /*! \brief Virtual worker function - by default it calls the user callback function. \remark The respective callback parameter format is chosen depending on whether clss is defined or not. */ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::Timer::Work() { if(cback) { if(clss) ((bool (*)(flext_base *,void *))cback)(clss,userdata); else cback(userdata); } } #include "flpopns.h" #endif // __FLEXT_TIMER_CPP flext-0-6-3/source/flutil.cpp000066400000000000000000000016311446466241400161570ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flutil.cpp \brief Implementation of the various utility functions. */ #ifndef __FLEXT_UTIL_CPP #define __FLEXT_UTIL_CPP #include "flext.h" #include #if FLEXT_OS == FLEXT_OS_WIN #include #endif #include "flpushns.h" FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::CopyMem(void *dst,const void *src,int bytes) { #if FLEXT_OS == FLEXT_OS_WIN MoveMemory(dst,src,bytes); #else memmove(dst,src,bytes); #endif } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ZeroMem(void *dst,int bytes) { #if FLEXT_OS == FLEXT_OS_WIN ZeroMemory(dst,bytes); #else memset(dst,0,bytes); #endif } #include "flpopns.h" #endif // __FLEXT_UTIL_CPP flext-0-6-3/source/flxlet.cpp000066400000000000000000000057771446466241400161750ustar00rootroot00000000000000/* flext - C++ layer for Max and Pure Data externals Copyright (c) 2001-2015 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ /*! \file flxlet.cpp \brief Implementation of the variable inlet/outlet functionality. */ #ifndef __FLEXT_XLET_CPP #define __FLEXT_XLET_CPP #include "flext.h" #include "flinternal.h" #include #include #include "flpushns.h" #define MAXLETS 256 FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext_base))::xlet FLEXT_CLASSDEF(flext_base))::inlist[MAXLETS]; FLEXT_TEMPIMPL(FLEXT_TEMPSUB(FLEXT_CLASSDEF(flext_base))::xlet FLEXT_CLASSDEF(flext_base))::outlist[MAXLETS]; FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::xlet::xlet(): tp(xlet_none),desc(NULL) {} FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_base))::xlet::~xlet() { if(desc) delete[] desc; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::xlet::Desc(const char *c) { if(desc) delete[] desc; if(c) { size_t l = strlen(c); desc = new char[l+1]; memcpy(desc,c,l+1); } else desc = NULL; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddInlet(int tp,int mult,const char *desc) { if(UNLIKELY(incnt+mult >= MAXLETS)) post("%s - too many inlets",thisName()); else for(int i = 0; i < mult; ++i) { xlet &x = inlist[incnt++]; x.tp = tp; x.Desc(desc); } } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddOutlet(int tp,int mult,const char *desc) { if(UNLIKELY(outcnt+mult >= MAXLETS)) post("%s - too many outlets",thisName()); else for(int i = 0; i < mult; ++i) { xlet &x = outlist[outcnt++]; x.tp = tp; x.Desc(desc); } } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::DescInlet(int ix,const char *d) { if(UNLIKELY(ix >= incnt)) post("%s - inlet %i not found",thisName(),ix); else inlist[ix].Desc(d); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::DescOutlet(int ix,const char *d) { if(UNLIKELY(ix >= incnt)) post("%s - outlet %i not found",thisName(),ix); else outlist[ix].Desc(d); } FLEXT_TEMPIMPL(unsigned long FLEXT_CLASSDEF(flext_base))::XletCode(int tp,...) { unsigned long code = 0; va_list marker; va_start(marker,tp); int cnt = 0; int arg = tp; for(; arg; ++cnt) { #ifdef FLEXT_DEBUG if(cnt > 9) { error("%s - Too many in/outlets defined - truncated to 9",thisName()); break; } #endif code = code*10+(int)arg; arg = va_arg(marker,int); } va_end(marker); return code; } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddInlets(unsigned long code) { for(; code; code /= 10) AddInlet(code%10); } FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddOutlets(unsigned long code) { for(; code; code /= 10) AddOutlet(code%10); } #include "flpopns.h" #endif // __FLEXT_XLET_CPP flext-0-6-3/source/lockfree/000077500000000000000000000000001446466241400157455ustar00rootroot00000000000000flext-0-6-3/source/lockfree/atomic_int.hpp000066400000000000000000000104321446466241400206040ustar00rootroot00000000000000// $Id$ // // Copyright (C) 2007 Tim Blechmann & Thomas Grill // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // $Revision$ // $LastChangedRevision$ // $LastChangedDate$ // $LastChangedBy$ #ifndef __LOCKFREE_ATOMIC_INT_HPP #define __LOCKFREE_ATOMIC_INT_HPP #include "prefix.hpp" namespace lockfree { #if defined(__GNUC__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) ) template class atomic_int { public: explicit atomic_int(T v = 0): value(v) { } operator T(void) const { return __sync_fetch_and_add(&value, 0); } void operator =(T v) { value = v; __sync_synchronize(); } T operator +=(T v) { return __sync_add_and_fetch(&value, v); } T operator -=(T v) { return __sync_sub_and_fetch(&value, v); } /* prefix operator */ T operator ++(void) { return __sync_add_and_fetch(&value, 1); } /* prefix operator */ T operator --(void) { return __sync_sub_and_fetch(&value, 1); } /* postfix operator */ T operator ++(int) { return __sync_fetch_and_add(&value, 1); } /* postfix operator */ T operator --(int) { return __sync_fetch_and_sub(&value, 1); } private: mutable T value; }; #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) template class atomic_int { public: explicit atomic_int(T v = 0): value(v) { } operator T(void) const { return __gnu_cxx::__exchange_and_add(&value, 0); } void operator =(T v) { value = v; } T operator +=(T v) { return __gnu_cxx::__exchange_and_add(&value, v) + v; } T operator -=(T v) { return __gnu_cxx::__exchange_and_add(&value, -v) - v; } /* prefix operator */ T operator ++(void) { return operator+=(1); } /* prefix operator */ T operator --(void) { return operator-=(1); } /* postfix operator */ T operator ++(int) { return __gnu_cxx::__exchange_and_add(&value, 1); } /* postfix operator */ T operator --(int) { return __gnu_cxx::__exchange_and_add(&value, -1); } private: mutable _Atomic_word value; }; #else /* emulate via CAS */ template class atomic_int { public: explicit atomic_int(T v = 0) { *this = v; } operator T(void) const { memory_barrier(); return value; } void operator =(T v) { value = v; memory_barrier(); } /* prefix operator */ T operator ++() { return *this += 1; } /* prefix operator */ T operator --() { return *this -= 1; } T operator +=(T v) { for(;;) { T newv = value+v; if(likely(CAS(&value,value,newv))) return newv; } } T operator -=(T v) { for(;;) { T newv = value-v; if(likely(CAS(&value,value,newv))) return newv; } } /* postfix operator */ T operator ++(int) { for(;;) { T oldv = value; if(likely(CAS(&value,oldv,oldv+1))) return oldv; } } /* postfix operator */ T operator --(int) { for(;;) { T oldv = value; if(likely(CAS(&value,oldv,oldv-1))) return oldv; } } private: T value; }; #endif } // namespace lockfree #endif /* __LOCKFREE_ATOMIC_INT_HPP */ flext-0-6-3/source/lockfree/atomic_ptr.hpp000066400000000000000000000053501446466241400206220ustar00rootroot00000000000000// $Id$ // // Copyright (C) 2007 Tim Blechmann & Thomas Grill // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // $Revision$ // $LastChangedRevision$ // $LastChangedDate$ // $LastChangedBy$ #ifndef __LOCKFREE_ATOMIC_PTR_HPP #define __LOCKFREE_ATOMIC_PTR_HPP #include "cas.hpp" #include "branch_hints.hpp" #include namespace lockfree { using std::size_t; template class atomic_ptr { public: atomic_ptr() {} atomic_ptr(const atomic_ptr &p): ptr(p.ptr),tag(p.tag) {} atomic_ptr(T *p,size_t t = 0): ptr(p),tag(t) {} /** atomic set operation */ inline atomic_ptr &operator =(const atomic_ptr &p) { for (;;) { atomic_ptr current(ptr, tag); if(likely(CAS(current, p))) return *this; } } inline atomic_ptr &operator()(T *p,size_t t) { return operator=(atomic_ptr(p, t) ); } inline bool operator ==(const atomic_ptr &p) const { return ptr == p.ptr && tag == p.tag; } inline bool operator !=(const atomic_ptr &p) const { return !operator ==(p); } inline T * getPtr() const { return ptr; } inline void setPtr(T * p) { ptr = p; } inline size_t getTag() const { return tag; } inline void setTag(size_t t) { tag = t; } inline size_t incTag() { return ++tag; } inline bool CAS(const atomic_ptr &oldval,const atomic_ptr &newval) { return lockfree::CAS2(this,oldval.ptr,oldval.tag,newval.ptr,newval.tag); } inline bool CAS(const atomic_ptr &oldval,T *newptr) { return lockfree::CAS2(this,oldval.ptr,oldval.tag,newptr,oldval.tag+1); } inline bool CAS(const T *oldptr,size_t oldtag,T *newptr) { return lockfree::CAS2(this,oldptr,oldtag,newptr,oldtag+1); } protected: T * volatile ptr; size_t volatile tag; }; } // namespace #endif /* __LOCKFREE_ATOMIC_PTR_HPP */ flext-0-6-3/source/lockfree/branch_hints.hpp000066400000000000000000000026421446466241400211240ustar00rootroot00000000000000// $Id$ // // branch hints // Copyright (C) 2007 Tim Blechmann // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // $Revision$ // $LastChangedRevision$ // $LastChangedDate$ // $LastChangedBy$ #ifndef __LOCKFREE_BRANCH_HINTS_HPP #define __LOCKFREE_BRANCH_HINTS_HPP namespace lockfree { /** \brief hint for the branch prediction */ inline bool likely(bool expr) { #ifdef __GNUC__ return __builtin_expect(expr, true); #else return expr; #endif } /** \brief hint for the branch prediction */ inline bool unlikely(bool expr) { #ifdef __GNUC__ return __builtin_expect(expr, false); #else return expr; #endif } } // namespace #endif /* __LOCKFREE_BRANCH_HINTS_HPP */ flext-0-6-3/source/lockfree/cas.hpp000066400000000000000000000173371446466241400172370ustar00rootroot00000000000000// $Id$ // // Copyright (C) 2007-2008 Tim Blechmann & Thomas Grill // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // $Revision$ // $LastChangedRevision$ // $LastChangedDate$ // $LastChangedBy$ #ifndef __LOCKFREE_CAS_H #define __LOCKFREE_CAS_H #include "prefix.hpp" #ifndef _WIN32 // pthreads are not available under Windows by default and we should not need them there # include #endif namespace lockfree { inline void memory_barrier() { #if defined(__GNUC__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) ) __sync_synchronize(); #elif defined(__GNUC__) && (defined(__i386__) || defined(__i686__)) asm("" : : : "memory"); #elif defined(_MSC_VER) && (_MSC_VER >= 1300) _ReadWriteBarrier(); #elif defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) OSMemoryBarrier(); #elif defined(AO_HAVE_nop_full) AO_nop_full(); #else # error no memory barrier implemented for this platform #endif } template inline bool CAS(volatile C * addr,D old,D nw) { #if defined(__GNUC__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) ) && (!defined USE_BLOCKING_CAS) return __sync_bool_compare_and_swap(addr, old, nw); #elif defined(_MSC_VER) assert((size_t(addr)&3) == 0); // a runtime check only for debug mode is somehow insufficient.... return _InterlockedCompareExchange(addr,nw,old) == old; #elif defined(_WIN32) || defined(_WIN64) assert((size_t(addr)&3) == 0); // a runtime check only for debug mode is somehow insufficient.... return InterlockedCompareExchange(addr,nw,old) == old; #elif defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) if(sizeof(D) == 4) return OSAtomicCompareAndSwap32(old,nw,addr); else if(sizeof(D) == 8) return OSAtomicCompareAndSwap64(old,nw,addr); else assert(false); #elif defined(AO_HAVE_compare_and_swap_full) && (!defined USE_BLOCKING_CAS) return AO_compare_and_swap_full(reinterpret_cast(addr), reinterpret_cast(old), reinterpret_cast(nw)); #else # ifdef __GNUC__ # warning blocking CAS emulation # else # pragma message("blocking CAS emulation") # endif pthread_mutex_t guard = PTHREAD_MUTEX_INITIALIZER; int status = pthread_mutex_lock(&guard); assert(!status); bool ret; if (*addr == old) { *addr = nw; ret = true; } else ret = false; int status2 = pthread_mutex_unlock(&guard); assert(!status2); return ret; #endif } template inline bool CAS2(C * addr,D old1,E old2,D new1,E new2) { #if defined(__GNUC__) && ((__GNUC__ > 4) || ( (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 2) ) ) && (defined(__i686__) || defined(__pentiumpro__) || defined(__nocona__) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) && (!defined USE_BLOCKING_CAS2) struct packed_c { D d; E e; }; union cu { packed_c c; long long l; }; cu old; old.c.d = old1; old.c.e = old2; cu nw; nw.c.d = new1; nw.c.e = new2; return __sync_bool_compare_and_swap_8(reinterpret_cast(addr), old.l, nw.l); #elif defined(__GNUC__) && ((__GNUC__ > 4) || ( (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 2) ) ) && (defined(__x86_64__) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)) && (!defined USE_BLOCKING_CAS2) struct packed_c { D d; E e; }; union cu { packed_c c; long long l; }; cu old; old.c.d = old1; old.c.e = old2; cu nw; nw.c.d = new1; nw.c.e = new2; return __sync_bool_compare_and_swap_16(reinterpret_cast(addr), old.l, nw.l); #elif defined(_MSC_VER) bool ok; __asm { # ifdef _WIN32 mov eax,[old1] mov edx,[old2] mov ebx,[new1] mov ecx,[new2] mov edi,[addr] lock cmpxchg8b [edi] # else mov rax,[old1] mov rdx,[old2] mov rbx,[new1] mov rcx,[new2] mov rdi,[addr] lock cmpxchg16b [rdi] # endif setz [ok] } return ok; #elif defined(__GNUC__) && (defined(__i386__) || defined(__i686__) || defined(__x86_64__)) && (!defined USE_BLOCKING_CAS2) char result; if(sizeof(D) == 4 && sizeof(E) == 4) { #ifndef __PIC__ __asm__ __volatile__("lock; cmpxchg8b %0; setz %1" : "=m"(*addr), "=q"(result) : "m"(*addr), "a" (old1), "d" (old2), "b" (new1), "c" (new2) : "memory"); #else __asm__ __volatile__("push %%ebx; movl %5,%%ebx; lock; cmpxchg8b %0; setz %1; pop %%ebx" : "=m"(*addr), "=q"(result) : "m"(*addr), "a" (old1), "d" (old2), "m" (new1), "c" (new2) : "memory"); #endif } else if(sizeof(D) == 8 && sizeof(E) == 8) { __asm__ __volatile__("lock; cmpxchg16b %0; setz %1" : "=m"(*addr), "=q"(result) : "m"(*addr), "a" (old1), "d" (old2), "b" (new1), "c" (new2) : "memory"); } else assert(false); return result != 0; #elif defined(AO_HAVE_double_compare_and_swap_full) && (!defined USE_BLOCKING_CAS2) if (sizeof(D) != sizeof(AO_t) || sizeof(E) != sizeof(AO_t)) { assert(false); return false; } return AO_compare_double_and_swap_double_full( reinterpret_cast(addr), static_cast(old2), reinterpret_cast(old1), static_cast(new2), reinterpret_cast(new1) ); #else # ifdef __GNUC__ # warning blocking CAS2 emulation # else # pragma message("blocking CAS2 emulation") # endif struct packed_c { D d; E e; }; volatile packed_c * packed_addr = reinterpret_cast(addr); pthread_mutex_t guard = PTHREAD_MUTEX_INITIALIZER; int status = pthread_mutex_lock(&guard); assert(!status); bool ret; if (packed_addr->d == old1 && packed_addr->e == old2) { packed_addr->d = new1; packed_addr->e = new2; ret = true; } else ret = false; int status2 = pthread_mutex_unlock(&guard); assert(!status2); return ret; #endif } } // namespace #endif /* __LOCKFREE_CAS_H */ flext-0-6-3/source/lockfree/fifo.hpp000066400000000000000000000144601446466241400174060ustar00rootroot00000000000000// $Id$ // // lock-free fifo queue from // Michael, M. M. and Scott, M. L., // "simple, fast and practical non-blocking and blocking concurrent queue algorithms" // // intrusive implementation for c++ // // Copyright (C) 2007 Tim Blechmann & Thomas Grill // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // $Revision$ // $LastChangedRevision$ // $LastChangedDate$ // $LastChangedBy$ #ifndef __LOCKFREE_FIFO_HPP #define __LOCKFREE_FIFO_HPP #include "cas.hpp" #include "atomic_ptr.hpp" #include "branch_hints.hpp" #ifdef HAVE_BOOST # include # include #else /* HAVE_BOOST */ # ifdef BOOST_STATIC_ASSERT # undef BOOST_STATIC_ASSERT # endif # define BOOST_STATIC_ASSERT(x) #endif /* HAVE_BOOST */ #include namespace lockfree { struct intrusive_fifo_node; typedef atomic_ptr intrusive_fifo_ptr_t; struct intrusive_fifo_node { intrusive_fifo_ptr_t next; struct fifo_node * data; }; struct fifo_node { intrusive_fifo_node *volatile node; protected: fifo_node(void) { node = new intrusive_fifo_node(); } ~fifo_node(void) { delete node; } template friend class intrusive_fifo; }; template class intrusive_fifo { BOOST_STATIC_ASSERT((boost::is_base_of::value)); public: intrusive_fifo(void) { /* dummy pointer for head/tail */ intrusive_fifo_node * dummy = new intrusive_fifo_node(); dummy->next(NULL,0); head_(dummy,0); tail_(dummy,0); } ~intrusive_fifo(void) { /* client must have freed all members already */ assert (empty()); delete head_.getPtr(); } bool empty() const { return head_.getPtr() == tail_.getPtr() || (!tail_.getPtr()); } void enqueue(T * instance) { /* volatile */ intrusive_fifo_node * node = static_cast(instance)->node; node->next.setPtr(NULL); node->data = static_cast(instance); for (;;) { intrusive_fifo_ptr_t tail(tail_); memory_barrier(); intrusive_fifo_ptr_t next(tail.getPtr()->next); memory_barrier(); if (likely(tail == tail_)) { if (next.getPtr() == 0) { if (tail.getPtr()->next.CAS(next,node)) { tail_.CAS(tail,node); return; } } else tail_.CAS(tail,next); } } } T* dequeue (void) { T * ret; for (;;) { intrusive_fifo_ptr_t head(head_); memory_barrier(); intrusive_fifo_ptr_t tail(tail_); /* volatile */ intrusive_fifo_node * next = head.getPtr()->next.getPtr(); memory_barrier(); if (likely(head == head_)) { if (head.getPtr() == tail.getPtr()) { if (next == 0) return 0; tail_.CAS(tail,next); } else { ret = static_cast(next->data); if (head_.CAS(head,next)) { ret->node = head.getPtr(); return ret; } } } } } private: intrusive_fifo_ptr_t head_,tail_; }; template class fifo_value_node: public fifo_node { public: fifo_value_node(T const & v): value(v) {} T value; }; template > class fifo : intrusive_fifo > { public: ~fifo() { fifo_value_node * node; while((node = intrusive_fifo >::dequeue()) != NULL) free(node); } void enqueue(T const & v) { intrusive_fifo >::enqueue(alloc(v)); } bool dequeue (T & v) { fifo_value_node * node = intrusive_fifo >::dequeue(); if(!node) return false; v = node->value; free(node); return true; } private: #if 0 inline fifo_value_node *alloc(const T &k) { fifo_value_node *node = allocator.allocate(1); allocator.construct(node,k); return node; } inline void free(fifo_value_node *n) { assert(n); allocator.destroy(n); allocator.deallocate(n,1); } #else // hmmm... static keyword brings 10% speedup... static inline fifo_value_node *alloc(const T &k) { return new fifo_value_node(k); } static inline void free(fifo_value_node *n) { assert(n); delete n; } #endif typename Alloc::template rebind >::other allocator; }; } #endif /* __LOCKFREE_FIFO_HPP */ flext-0-6-3/source/lockfree/prefix.hpp000066400000000000000000000033541446466241400177600ustar00rootroot00000000000000// $Id$ // // Copyright (C) 2007 Tim Blechmann & Thomas Grill // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // $Revision$ // $LastChangedRevision$ // $LastChangedDate$ // $LastChangedBy$ #ifndef __LOCKFREE_PREFIX_H #define __LOCKFREE_PREFIX_H #include #ifdef USE_ATOMIC_OPS #define AO_REQUIRE_CAS #define AO_USE_PENTIUM4_INSTRS extern "C" { #include } #endif #ifdef _WIN32 #include #endif #ifdef __APPLE__ #include #else #if defined(__GLIBCPP__) || defined(__GLIBCXX__) #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) #include #else #include #endif #endif #endif #if defined(_MSC_VER) // \note: Must use /Oi option for VC++ to enable intrinsics extern "C" { void __cdecl _ReadWriteBarrier(); LONG __cdecl _InterlockedCompareExchange(LONG volatile* Dest,LONG Exchange, LONG Comp); } #endif #endif /* __LOCKFREE_PREFIX_H */ flext-0-6-3/source/lockfree/stack.hpp000066400000000000000000000077151446466241400175750ustar00rootroot00000000000000// $Id$ // // lock-free stack // // Copyright (C) 2007 Tim Blechmann & Thomas Grill // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // $Revision$ // $LastChangedRevision$ // $LastChangedDate$ // $LastChangedBy$ #ifndef __LOCKFREE_STACK_HPP #define __LOCKFREE_STACK_HPP #include "cas.hpp" #include "atomic_ptr.hpp" #include "branch_hints.hpp" #include // for std::allocator #if HAVE_BOOST # include # include #else # define BOOST_STATIC_ASSERT(x) #endif namespace lockfree { //! nodes for the intrusive_stack must be derived from that class stack_node { template friend class intrusive_stack; public: stack_node(): next(NULL) {} private: atomic_ptr next; }; //! intrusive lock-free stack implementation with T being the node type (inherited from stack_node) template class intrusive_stack { BOOST_STATIC_ASSERT((boost::is_base_of::value)); public: intrusive_stack(): head(NULL) {} ~intrusive_stack() { assert(empty()); } bool empty() const { return !head.getPtr(); } void push(T *node) { assert(!node->next.getPtr()); while(unlikely(!head.CAS(node->next = head,node))); } T *pop() { for(;;) { atomic_ptr current(head); T *node = static_cast(current.getPtr()); if(!node || likely(head.CAS(current,node->next.getPtr()))) { if(node) node->next.setPtr(NULL); return node; } } } private: atomic_ptr head; }; //! node type used by non-intrusive stack template class stack_value_node : public stack_node { public: stack_value_node(T const &v): value(v) {} T value; }; //! non-intrusive lock-free stack template > class stack : intrusive_stack > { public: ~stack() { // delete remaining elements stack_value_node * node; while((node = intrusive_stack >::pop()) != NULL) free(node); } void push(T const &v) { intrusive_stack >::push(alloc(v)); } bool pop(T &v) { stack_value_node *node = intrusive_stack >::pop(); if(!node) return false; v = node->value; free(node); return true; } private: inline stack_value_node *alloc(const T &k) { stack_value_node *node = allocator.allocate(1); allocator.construct(node,k); return node; } inline void free(stack_value_node *n) { assert(n); allocator.destroy(n); allocator.deallocate(n,1); } typename Alloc::template rebind >::other allocator; }; } // namespace #endif flext-0-6-3/tutorial/000077500000000000000000000000001446466241400145165ustar00rootroot00000000000000flext-0-6-3/tutorial/1_simple1/000077500000000000000000000000001446466241400163105ustar00rootroot00000000000000flext-0-6-3/tutorial/1_simple1/Makefile.am000066400000000000000000000000441446466241400203420ustar00rootroot00000000000000NAME = simple1 include ../common.mk flext-0-6-3/tutorial/1_simple1/main.cpp000066400000000000000000000035121446466241400177410ustar00rootroot00000000000000/* flext tutorial - simple 1 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of a simple object doing a float inversion */ // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif // define the class that stands for a pd/Max object // Attention: the class name must be the same as the object name!! (without an eventual ~) // Special names are possible with the usage of libraries (see the lib1 tutorial example) class simple1: // inherit from basic flext class public flext_base { // obligatory flext header (class name,base class name) FLEXT_HEADER(simple1,flext_base) public: // constructor simple1() { // define inlets: // first inlet must always be of type anything (or signal for dsp objects) AddInAnything(); // add one inlet for any message // define outlets: AddOutFloat(); // add one float outlet (has index 0) // register methods FLEXT_ADDMETHOD(0,m_float); // register method (for float messages) "m_float" for inlet 0 } protected: void m_float(float input) // method for float values { float result; if(input == 0) { // special case 0 post("%s - zero can't be inverted!",thisName()); result = 0; } else // normal case result = 1/input; // output value to outlet ToOutFloat(0,result); // (0 stands for the outlet index 0 - the leftmost outlet) } private: FLEXT_CALLBACK_1(m_float,float) // callback for method "m_float" (with one float argument) }; // instantiate the class FLEXT_NEW("simple1",simple1) flext-0-6-3/tutorial/1_simple1/package.txt000066400000000000000000000000351446466241400204420ustar00rootroot00000000000000NAME=simple1 SRCS=main.cpp flext-0-6-3/tutorial/1_simple2/000077500000000000000000000000001446466241400163115ustar00rootroot00000000000000flext-0-6-3/tutorial/1_simple2/Makefile.am000066400000000000000000000000441446466241400203430ustar00rootroot00000000000000NAME = simple2 include ../common.mk flext-0-6-3/tutorial/1_simple2/main.cpp000066400000000000000000000034761446466241400177530ustar00rootroot00000000000000/* flext tutorial - simple 2 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of a simple object doing a float addition */ // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif class simple2: public flext_base { FLEXT_HEADER(simple2,flext_base) public: // constructor with float argument simple2(float init); protected: void m_float1(float f); void m_float2(float f); // stored argument of right inlet float arg; private: // FLEXT_CALLBACK_F(...) is a shortcut for FLEXT_CALLBACK_1(...,float) FLEXT_CALLBACK_F(m_float1) // callback for method "m_float1" (with one float argument) FLEXT_CALLBACK_F(m_float2) // callback for method "m_float2" (with one float argument) }; // instantiate the class (constructor has one float argument) FLEXT_NEW_1("simple2",simple2,float) simple2::simple2(float init): arg(init) // store argument { // define inlets AddInAnything(); // first inlet of type anything (index 0) AddInFloat(); // additional float inlet (index 1) // define outlets AddOutFloat(); // one float outlet (has index 0) // register methods FLEXT_ADDMETHOD(0,m_float1); // register method (for floats) "m_float1" for inlet 0 FLEXT_ADDMETHOD(1,m_float2); // register method (for floats) "m_float2" for inlet 1 } void simple2::m_float1(float f) { float res; res = arg+f; // output value to outlet ToOutFloat(0,res); // (0 stands for the outlet index 0) } void simple2::m_float2(float f) { // store float arg = f; } flext-0-6-3/tutorial/1_simple2/package.txt000066400000000000000000000000351446466241400204430ustar00rootroot00000000000000NAME=simple2 SRCS=main.cpp flext-0-6-3/tutorial/1_simple3/000077500000000000000000000000001446466241400163125ustar00rootroot00000000000000flext-0-6-3/tutorial/1_simple3/Makefile.am000066400000000000000000000000441446466241400203440ustar00rootroot00000000000000NAME = simple3 include ../common.mk flext-0-6-3/tutorial/1_simple3/main.cpp000066400000000000000000000042261446466241400177460ustar00rootroot00000000000000/* flext tutorial - simple 3 Copyright (c) 2002-2006 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of an object digesting several "tagged" messages */ // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500) #error You need at least flext version 0.5.0 #endif class simple3: public flext_base { FLEXT_HEADER(simple3,flext_base) public: // constructor with no arguments simple3(); protected: void m_tag(); void m_tag_and_int(int i); void m_sym(t_symbol *s); // override default flext help function void m_help(); private: FLEXT_CALLBACK(m_tag) // callback for method "m_tag" (no arguments) FLEXT_CALLBACK_I(m_tag_and_int) // callback for method "m_tag_and_int" (int arguments) FLEXT_CALLBACK_S(m_sym) // callback for method "m_sym" (with one symbol argument) FLEXT_CALLBACK(m_help) // callback for method "m_help" (no arguments) }; // instantiate the class (constructor takes no arguments) FLEXT_NEW("simple3",simple3) simple3::simple3() { // define inlets AddInAnything(); // add inlet of type anything (index 0) // register methods FLEXT_ADDMETHOD_(0,"born",m_tag); // register method for tag "born" FLEXT_ADDMETHOD_(0,"to",m_tag); // register method for tag "to" FLEXT_ADDMETHOD_(0,"hula",m_tag); // register method for tag "hula" FLEXT_ADDMETHOD_I(0,"hula",m_tag_and_int); // register method for tag "hula" and int argument FLEXT_ADDMETHOD(0,m_sym); // register method for all other symbols FLEXT_ADDMETHOD_(0,"help",m_help); // register method for "help" message } void simple3::m_tag() { post("tag recognized"); } void simple3::m_tag_and_int(int i) { post("tag recognized (has int arg: %i)",i); } void simple3::m_sym(t_symbol *s) { post("symbol: %s",GetString(s)); } void simple3::m_help() { // post a help message // thisName() returns a char * for the object name post("%s - example for tagged messages",thisName()); } flext-0-6-3/tutorial/1_simple3/package.txt000066400000000000000000000000351446466241400204440ustar00rootroot00000000000000NAME=simple3 SRCS=main.cpp flext-0-6-3/tutorial/2_adv1/000077500000000000000000000000001446466241400155725ustar00rootroot00000000000000flext-0-6-3/tutorial/2_adv1/Makefile.am000066400000000000000000000000411446466241400176210ustar00rootroot00000000000000NAME = adv1 include ../common.mk flext-0-6-3/tutorial/2_adv1/main.cpp000066400000000000000000000046261446466241400172320ustar00rootroot00000000000000/* flext tutorial - advanced 1 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of a simplified prepend object */ #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401) #error You need at least flext version 0.4.1 #endif class adv1: public flext_base { FLEXT_HEADER(adv1,flext_base) public: // constructor with variable argument list adv1(int argc,t_atom *argv); protected: void m_any(const t_symbol *s,int argc,t_atom *argv); // method which digests anything AtomList lst; private: FLEXT_CALLBACK_A(m_any); // callback for method "m_any" (with anything argument) }; // instantiate the class (constructor has a variable argument list) // note the two words in the string: prepend acts as an alias for adv1! FLEXT_NEW_V("adv1 prepend",adv1) // constructor adv1::adv1(int argc,t_atom *argv) { AddInAnything(); // one inlet that can receive anything AddOutAnything(); // one outlet for anything // register method FLEXT_ADDMETHOD(0,m_any); // register method "m_any" for inlet 0 if(argc != 0) { // check for arg count // store arg list lst(argc,argv); } else { // no args given post("%s - no arguments given",thisName()); // tell flext that the initialization was not successful... object will not live InitProblem(); } } // method void adv1::m_any(const t_symbol *s,int argc,t_atom *argv) { // reserve space for as many atoms as possibly necessary AtomList result(lst.Count()+argc+2); // ix is our counter of atoms to output int ix = 0; int i = 0; if(!IsSymbol(lst[0])) { // if first element to prepend is no symbol then make it a "list" SetSymbol(result[ix++],sym_list); } // copy atoms to prepend to result list for(; i < lst.Count(); ++i) CopyAtom(&result[ix++],&lst[i]); // if anything is no "list" or "float" then append it to result list if(s != sym_list && s != sym_float #if FLEXT_SYS == FLEXT_SYS_MAX && s != sym_int // in Max integers are system data types #endif ) SetSymbol(result[ix++],s); // append pending arguments to result list for(i = 0; i < argc; ++i) CopyAtom(&result[ix++],argv+i); // output result list as an anything ToOutAnything(0,GetSymbol(result[0]),ix-1,result.Atoms()+1); } flext-0-6-3/tutorial/2_adv1/package.txt000066400000000000000000000000321446466241400177210ustar00rootroot00000000000000NAME=adv1 SRCS=main.cpp flext-0-6-3/tutorial/2_adv2/000077500000000000000000000000001446466241400155735ustar00rootroot00000000000000flext-0-6-3/tutorial/2_adv2/Makefile.am000066400000000000000000000000411446466241400176220ustar00rootroot00000000000000NAME = adv2 include ../common.mk flext-0-6-3/tutorial/2_adv2/main.cpp000066400000000000000000000043471446466241400172330ustar00rootroot00000000000000/* flext tutorial - advanced 2 Copyright (c) 2002-2006 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an optimized version of the example "simple 3" It has the exact same functionality but methods are registered at class setup opposed to object setup (in the constructor) in "simple 3" The advantage of this lies in the fact that the message database needs only be constructed once for all objects, namely on creation of the first object of this class. All objects [adv2] will share the same database, saving memory. */ // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500) #error You need at least flext version 0.5.0 #endif class adv2: public flext_base { // flext header with a setup function called "setup" FLEXT_HEADER_S(adv2,flext_base,setup) public: adv2(); protected: void m_tag(); void m_tag_and_int(int i); void m_sym(t_symbol *s); void m_help(); private: // define the _static_ class setup function static void setup(t_classid c); FLEXT_CALLBACK(m_tag) FLEXT_CALLBACK_I(m_tag_and_int) FLEXT_CALLBACK_S(m_sym) FLEXT_CALLBACK(m_help) }; // instantiate the class (constructor takes no arguments) FLEXT_NEW("adv2",adv2) adv2::adv2() { // define inlets AddInAnything(); // add inlet of type anything (index 0) } void adv2::setup(t_classid c) { // register methods: // notice the naming FLEXT_CADD_METHOD* instead of FLEXT_ADD_METHOD* // there is also an additional parameter c pointing to the class definition FLEXT_CADDMETHOD_(c,0,"born",m_tag); FLEXT_CADDMETHOD_(c,0,"to",m_tag); FLEXT_CADDMETHOD_(c,0,"hula",m_tag); FLEXT_CADDMETHOD_I(c,0,"hula",m_tag_and_int); FLEXT_CADDMETHOD(c,0,m_sym); FLEXT_CADDMETHOD_(c,0,"help",m_help); } void adv2::m_tag() { post("tag recognized"); } void adv2::m_tag_and_int(int i) { post("tag recognized (has int arg: %i)",i); } void adv2::m_sym(t_symbol *s) { post("symbol: %s",GetString(s)); } void adv2::m_help() { post("%s - example for tagged messages",thisName()); } flext-0-6-3/tutorial/2_adv2/package.txt000066400000000000000000000000321446466241400177220ustar00rootroot00000000000000NAME=adv2 SRCS=main.cpp flext-0-6-3/tutorial/2_adv3/000077500000000000000000000000001446466241400155745ustar00rootroot00000000000000flext-0-6-3/tutorial/2_adv3/Makefile.am000066400000000000000000000000411446466241400176230ustar00rootroot00000000000000NAME = adv3 include ../common.mk flext-0-6-3/tutorial/2_adv3/main.cpp000066400000000000000000000101251446466241400172230ustar00rootroot00000000000000/* flext tutorial - advanced 3 Copyright (c) 2002-2006 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is a port of Iohannes Zmölnigs "counter" example to the flext paradigm. Find the original at http://iem.kug.ac.at/pd/externals-HOWTO/node5.html The functionality is exactly the same, with one exception: flext doesn't support default arguments, hence a message "bound 1" will translate into "bound 1 0" in the original example, but won't be recognized with flext. This can be easily circumvented by using a method digesting a variable argument list, but was omitted for the sake of clearness. Apart from that you'll notice several differences to the original C object: - with flext, callbacks have to be declared for all registered methods - Flext allows the full usage of integer types - there are no real "passive" methods with flext. These can be emulated by methods, or more flexibly, attributes (see example "attr3") - Help symbols can't be defined that freely. This is because in Max/MSP help files always have the name of the object with a suffix .help appended. However with flext, a path to the respective help file may be specified */ // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 501) #error You need at least flext version 0.5.1 #endif class adv3: public flext_base { FLEXT_HEADER_S(adv3,flext_base,setup) public: // constructor with no arguments adv3(int argc,t_atom *argv): i_step(1) { // --- initialize bounds and step size --- int f1 = 0,f2 = 0; switch(argc) { default: case 3: i_step = GetInt(argv[2]); case 2: f2 = GetInt(argv[1]); case 1: f1 = GetInt(argv[0]); case 0: ; } if(argc < 2) f2 = f1; m_bound(f1,f2); i_count = i_down; // --- define inlets and outlets --- AddInAnything("bang, reset, etc."); // default inlet AddInList("bounds (2 element list)"); // inlet for bounds AddInInt("step size"); // inlet for step size AddOutInt("counter"); // outlet for integer count AddOutBang("overflow bang"); // outlet for bang } protected: void m_reset() { i_count = i_down; } void m_set(int argc,t_atom *argv) { i_count = argc?GetAInt(argv[0]):0; } void m_bang() { int f = i_count; i_count += i_step; if(i_down != i_up) { if((i_step > 0) && (i_count > i_up)) { i_count = i_down; ToOutBang(1); } else if(i_count < i_down) { i_count = i_up; ToOutBang(1); } } ToOutInt(0,f); } void m_bound(int f1,int f2) { i_down = f1 < f2?f1:f2; i_up = f1 > f2?f1:f2; } void m_step(int s) { i_step = s; } int i_count,i_down,i_up,i_step; private: static void setup(t_classid c) { // --- set up methods (class scope) --- // register a bang method to the default inlet (0) FLEXT_CADDBANG(c,0,m_bang); // set up tagged methods for the default inlet (0) // the underscore _ after CADDMETHOD indicates that a message tag is used // no, variable list or anything and all single arguments are recognized automatically, ... FLEXT_CADDMETHOD_(c,0,"reset",m_reset); FLEXT_CADDMETHOD_(c,0,"set",m_set); // ..., more complex types (combinations of types) have to be specified explicitly FLEXT_CADDMETHOD_II(c,0,"bound",m_bound); // two int arguments // set up methods for inlets 1 and 2 // no message tag used FLEXT_CADDMETHOD(c,1,m_bound); // variable arg type recognized automatically FLEXT_CADDMETHOD(c,2,m_step); // single int arg also recognized automatically } // for every registered method a callback has to be declared FLEXT_CALLBACK(m_bang) FLEXT_CALLBACK(m_reset) FLEXT_CALLBACK_V(m_set) FLEXT_CALLBACK_II(m_bound) FLEXT_CALLBACK_I(m_step) }; // instantiate the class (constructor has a variable argument list) // let "counter" be an alternative name // after the colon define the path/name of the help file (a path has a trailing /, a file has not) FLEXT_NEW_V("adv3 counter,help/",adv3) flext-0-6-3/tutorial/2_adv3/package.txt000066400000000000000000000000321446466241400177230ustar00rootroot00000000000000NAME=adv3 SRCS=main.cpp flext-0-6-3/tutorial/3_attr1/000077500000000000000000000000001446466241400157735ustar00rootroot00000000000000flext-0-6-3/tutorial/3_attr1/Makefile.am000066400000000000000000000000421446466241400200230ustar00rootroot00000000000000NAME = attr1 include ../common.mk flext-0-6-3/tutorial/3_attr1/main.cpp000066400000000000000000000034371446466241400174320ustar00rootroot00000000000000/* flext tutorial - attributes 1 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of a simple object doing a float addition It is a variation of the tutorial "simple 2" */ // IMPORTANT: enable attribute processing (specify before inclusion of flext headers!) // For clarity, this is done here, but you'd better specify it as a compiler definition // FLEXT_ATTRIBUTES must be 0 or 1, #define FLEXT_ATTRIBUTES 1 // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif class attr1: public flext_base { FLEXT_HEADER(attr1,flext_base) public: // constructor attr1(); protected: void m_trigger(float f); // stored argument float arg; private: // callback for method "m_trigger" (with one float argument) FLEXT_CALLBACK_F(m_trigger) // define attribute callbacks for variable "arg" (with GET and SET properties) FLEXT_ATTRVAR_F(arg) }; // instantiate the class FLEXT_NEW("attr1",attr1) attr1::attr1(): arg(0) // initialize argument { // define inlets AddInAnything(); // first inlet of type anything (index 0) // define outlets AddOutFloat(); // one float outlet (has index 0) // register methods FLEXT_ADDMETHOD(0,m_trigger); // register method (for floats) "m_trigger" for inlet 0 FLEXT_ADDATTR_VAR1("arg",arg); // register attribute "arg" with variable arg } void attr1::m_trigger(float f) { float res = arg+f; // output value to outlet ToOutFloat(0,res); // (0 stands for the outlet index 0) } flext-0-6-3/tutorial/3_attr1/package.txt000066400000000000000000000000331446466241400201230ustar00rootroot00000000000000NAME=attr1 SRCS=main.cpp flext-0-6-3/tutorial/3_attr2/000077500000000000000000000000001446466241400157745ustar00rootroot00000000000000flext-0-6-3/tutorial/3_attr2/Makefile.am000066400000000000000000000000421446466241400200240ustar00rootroot00000000000000NAME = attr2 include ../common.mk flext-0-6-3/tutorial/3_attr2/main.cpp000066400000000000000000000106671446466241400174360ustar00rootroot00000000000000/* flext tutorial - attributes 2 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of an object doing various float operations. Methods and attributes are registered at class level (opposed to object level in example "attr1"). For details, see also example "adv2" */ // IMPORTANT: enable attribute processing (specify before inclusion of flext headers!) // For clarity, this is done here, but you'd better specify it as a compiler definition // FLEXT_ATTRIBUTES must be 0 or 1, #define FLEXT_ATTRIBUTES 1 // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401) #error You need at least flext version 0.4.1 #endif #include class attr2: public flext_base { // compulsory flext header with a class setup function FLEXT_HEADER_S(attr2,flext_base,setup) public: // constructor attr2(); protected: void m_trigger(float f); // stored argument of operation float arg; // stored result float res; enum operation { op_set,op_add,op_sub,op_mul,op_div,op_pow } op; static const t_symbol *sym_set,*sym_add,*sym_sub,*sym_div,*sym_mul,*sym_pow; private: static void setup(t_classid); // callback for method "m_trigger" (with one float argument) FLEXT_CALLBACK_F(m_trigger) // define attribute callbacks for variable "arg" ("ATTRVAR" means GET and SET) FLEXT_ATTRVAR_F(arg) // define attribute callbacks for variable "res" (GET only) FLEXT_ATTRGET_F(res) // methods for getting/setting the operation mode void opget(const t_symbol *&s) const; void opset(const t_symbol *&s); // define attribute callbacks for variable "res" (GET only) FLEXT_CALLGET_S(opget) FLEXT_CALLSET_S(opset) }; // instantiate the class FLEXT_NEW("attr2",attr2) // instantiate static variables const t_symbol *attr2::sym_set, *attr2::sym_add,*attr2::sym_sub, *attr2::sym_div,*attr2::sym_mul, *attr2::sym_pow; void attr2::setup(t_classid c) { // Upon class creation setup some symbols // This is done only upon creation of of the first "attr2" object sym_set = MakeSymbol("="); sym_add = MakeSymbol("+"); sym_sub = MakeSymbol("-"); sym_mul = MakeSymbol("*"); sym_div = MakeSymbol("/"); sym_pow = MakeSymbol("**"); // setup methods and attributes at class scope // register method (for floats) "m_trigger" for inlet 0 FLEXT_CADDMETHOD(c,0,m_trigger); // register attribute "arg" with the variable "arg" FLEXT_CADDATTR_VAR1(c,"arg",arg); // register attribute "result" with variable "res" FLEXT_CADDATTR_GET(c,"result",res); // register attribute "op" with methods "opget" and "opset" FLEXT_CADDATTR_VAR(c,"op",opget,opset); } attr2::attr2(): arg(0),res(0), // initialize argument and result op(op_set) // initialize operation { // define inlets AddInAnything(); // first inlet of type anything (index 0) // define outlets AddOutFloat(); // one float outlet (has index 0) } // receive an operand, do the math operation and trigger the output void attr2::m_trigger(float f) { switch(op) { case op_set: res = f; break; case op_add: res = f+arg; break; case op_sub: res = f-arg; break; case op_mul: res = f*arg; break; case op_div: if(arg) res = f/arg; else { post("%s - argument to division is 0: result set to 0",thisName()); res = 0; } break; case op_pow: res = (float)pow(f,arg); break; #ifdef FLEXT_DEBUG default: ERRINTERNAL(); // operation not defined #endif } // output value to outlet ToOutFloat(0,res); // (0 stands for the outlet index 0) } // report the operation mode void attr2::opget(const t_symbol *&s) const { switch(op) { case op_set: s = sym_set; break; case op_add: s = sym_add; break; case op_sub: s = sym_sub; break; case op_mul: s = sym_mul; break; case op_div: s = sym_div; break; case op_pow: s = sym_pow; break; #ifdef FLEXT_DEBUG default: ERRINTERNAL(); // operation not defined #endif } } // set the operation mode void attr2::opset(const t_symbol *&s) { if(s == sym_set) op = op_set; else if(s == sym_add) op = op_add; else if(s == sym_sub) op = op_sub; else if(s == sym_mul) op = op_mul; else if(s == sym_div) op = op_div; else if(s == sym_pow) op = op_pow; else { post("%s - operation is not defined, set to =",thisName()); op = op_set; } } flext-0-6-3/tutorial/3_attr2/package.txt000066400000000000000000000000331446466241400201240ustar00rootroot00000000000000NAME=attr2 SRCS=main.cpp flext-0-6-3/tutorial/3_attr3/000077500000000000000000000000001446466241400157755ustar00rootroot00000000000000flext-0-6-3/tutorial/3_attr3/Makefile.am000066400000000000000000000000421446466241400200250ustar00rootroot00000000000000NAME = attr3 include ../common.mk flext-0-6-3/tutorial/3_attr3/main.cpp000066400000000000000000000075571446466241400174430ustar00rootroot00000000000000/* flext tutorial - attributes 3 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is tutorial example "advanced 3" with the usage of attributes. */ // IMPORTANT: enable attribute processing (specify before inclusion of flext headers!) // For clarity, this is done here, but you'd better specify it as a compiler definition // FLEXT_ATTRIBUTES must be 0 or 1, #define FLEXT_ATTRIBUTES 1 // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401) #error You need at least flext version 0.4.1 #endif class attr3: public flext_base { FLEXT_HEADER_S(attr3,flext_base,setup) public: // constructor with no arguments // initial values are set by attributes at creation time (see help file) attr3(): // initialize data members i_down(0),i_up(0),i_count(0),i_step(1) { // --- define inlets and outlets --- AddInAnything(); // default inlet AddInList(); // inlet for bounds AddInInt(); // inlet for step size AddOutInt(); // outlet for integer count AddOutBang(); // outlet for bang } protected: void m_reset() { i_count = i_down; } void m_set(int argc,t_atom *argv) { i_count = argc?GetAInt(argv[0]):0; } void m_bang() { int f = i_count; i_count += i_step; if(i_down != i_up) { if((i_step > 0) && (i_count > i_up)) { i_count = i_down; ToOutBang(1); } else if(i_count < i_down) { i_count = i_up; ToOutBang(1); } } ToOutInt(0,f); } void m_bounds(int f1,int f2) { i_down = f1 < f2?f1:f2; i_up = f1 > f2?f1:f2; } void m_step(int s) { i_step = s; } // setter method of bounds variables void ms_bounds(const AtomList &l) { if(l.Count() == 2 && CanbeInt(l[0]) && CanbeInt(l[1])) // if it is a two element integer list use m_bounds method m_bounds(GetAInt(l[0]),GetAInt(l[1])); else // else post a warning post("%s - 'bounds' needs two integer parameters",thisName()); } // getter method of bounds variables void mg_bounds(AtomList &l) const { l(2); // initialize two element list SetInt(l[0],i_down); // set first element SetInt(l[1],i_up); // set second element } int i_count,i_down,i_up,i_step; private: static void setup(t_classid c) { // --- set up methods (class scope) --- // register a bang method to the default inlet (0) FLEXT_CADDBANG(c,0,m_bang); // set up tagged methods for the default inlet (0) FLEXT_CADDMETHOD_(c,0,"reset",m_reset); FLEXT_CADDMETHOD_(c,0,"set",m_set); // set up methods for inlets 1 and 2 // no message tag used FLEXT_CADDMETHOD(c,1,m_bounds); // variable arg type recognized automatically FLEXT_CADDMETHOD(c,2,m_step); // single int arg also recognized automatically // --- set up attributes (class scope) --- // these have equally named getters and setters // see the wrappers below FLEXT_CADDATTR_VAR1(c,"count",i_count); FLEXT_CADDATTR_VAR1(c,"step",i_step); // bounds has differently named getter and setter functions // see the wrappers below FLEXT_CADDATTR_VAR(c,"bounds",mg_bounds,ms_bounds); } // normal method callbacks for bang and reset FLEXT_CALLBACK(m_bang) FLEXT_CALLBACK(m_reset) FLEXT_CALLBACK_V(m_set) // normal method wrapper for m_set FLEXT_ATTRVAR_I(i_count) // wrapper functions (get and set) for integer variable i_count FLEXT_CALLBACK_II(m_bounds) // normal method wrapper for m_bounds FLEXT_CALLVAR_V(mg_bounds,ms_bounds) // getter and setter method of bounds FLEXT_CALLBACK_I(m_step) // normal method wrapper for m_step FLEXT_ATTRVAR_I(i_step) // wrapper functions (get and set) for integer variable i_step }; // instantiate the class (constructor takes no arguments) FLEXT_NEW("attr3",attr3) flext-0-6-3/tutorial/3_attr3/package.txt000066400000000000000000000000331446466241400201250ustar00rootroot00000000000000NAME=attr3 SRCS=main.cpp flext-0-6-3/tutorial/4_bind1/000077500000000000000000000000001446466241400157365ustar00rootroot00000000000000flext-0-6-3/tutorial/4_bind1/Makefile.am000066400000000000000000000000421446466241400177660ustar00rootroot00000000000000NAME = bind1 include ../common.mk flext-0-6-3/tutorial/4_bind1/main.cpp000066400000000000000000000072471446466241400174000ustar00rootroot00000000000000/* flext tutorial - bind 1 Copyright (c) 2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of a simple object demonstrating method to symbol binding and message forwarding */ // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif // define the class that stands for a pd/Max object class bind1: // inherit from basic flext class public flext_base { // obligatory flext header (class name,base class name) featuring a setup function FLEXT_HEADER_S(bind1,flext_base,setup) public: // constructor with no arguments bind1() { // define inlets: // first inlet must always be of type anything (or signal for dsp objects) AddInAnything("message inlet"); // add one inlet for any message AddInAnything("forwarding inlet"); // add one inlet for any message AddOutAnything("bound message"); // output received bound message } /* no destructor necessary here: flext frees all eventually remaining bound symbols when the object is destroyed (but NOT the data that can be passed via the FLEXT_BINDMETHOD call!) */ protected: const t_symbol *bufname; buffer *buf; // bind object void m_bind(const t_symbol *s) { if(!Bind(s)) { post("%s (%s) - Binding failed",thisName(),GetString(thisTag())); } } // unbind object void m_unbind(const t_symbol *s) { if(!Unbind(s)) { post("%s (%s) - Binding failed",thisName(),GetString(thisTag())); } } // bind method void m_bindmethod(const t_symbol *s) { if(!FLEXT_BINDMETHOD(s,m_bound,NULL)) { post("%s (%s) - Binding failed",thisName(),GetString(thisTag())); } } // unbind method void m_unbindmethod(const t_symbol *s) { if(!FLEXT_UNBINDMETHOD(s)) { post("%s (%s) - Binding failed",thisName(),GetString(thisTag())); } } // forward message void m_forward(const t_symbol *s,int argc,const t_atom *argv) { Forward(s,argc,argv); } // method for symbol-bound messages void m_bound(const t_symbol *sym,int argc,const t_atom *argv,void *data) { ToOutAnything(0,sym,argc,argv); } // method for binding test void m_test(float value) { post("%s - TEST METHOD: value %f",thisName(),value); } private: static void setup(t_classid c) { // register methods FLEXT_CADDMETHOD_(c,0,"bind",m_bind); // register method "bind" for inlet 0 FLEXT_CADDMETHOD_(c,0,"unbind",m_unbind); // register method "unbind" for inlet 0 FLEXT_CADDMETHOD_(c,0,"bindmethod",m_bindmethod); // register method "bindmethod" for inlet 0 FLEXT_CADDMETHOD_(c,0,"unbindmethod",m_unbindmethod); // register method "unbindmethod" for inlet 0 FLEXT_CADDMETHOD_(c,0,"test",m_test); // register method m_test for inlet 0 FLEXT_CADDMETHOD(c,1,m_forward); // register method m_forward for inlet 1 } FLEXT_CALLBACK_S(m_bind) // wrapper for method m_bind (with symbol argument) FLEXT_CALLBACK_S(m_unbind) // wrapper for method m_unbind (with symbol argument) FLEXT_CALLBACK_S(m_bindmethod) // wrapper for method m_bindmethod (with symbol argument) FLEXT_CALLBACK_S(m_unbindmethod) // wrapper for method m_unbindmethod (with symbol argument) FLEXT_CALLBACK_A(m_forward) // wrapper for method m_forward (with anything argument) FLEXT_CALLBACK_AX(m_bound) // wrapper for method m_bound (anything+data arguments) FLEXT_CALLBACK_F(m_test) // wrapper for method m_test (one float argument) }; // instantiate the class FLEXT_NEW("bind1",bind1) flext-0-6-3/tutorial/4_bind1/package.txt000066400000000000000000000000331446466241400200660ustar00rootroot00000000000000NAME=bind1 SRCS=main.cpp flext-0-6-3/tutorial/4_buffer1/000077500000000000000000000000001446466241400162735ustar00rootroot00000000000000flext-0-6-3/tutorial/4_buffer1/Makefile.am000066400000000000000000000000441446466241400203250ustar00rootroot00000000000000NAME = buffer1 include ../common.mk flext-0-6-3/tutorial/4_buffer1/main.cpp000066400000000000000000000145271446466241400177340ustar00rootroot00000000000000/* flext tutorial - buffer 1 Copyright (c) 2003-2010 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of a simple object doing some basic buffer operation */ // IMPORTANT: enable attribute processing (specify before inclusion of flext headers!) // For clarity, this is done here, but you'd better specify it as a compiler definition // FLEXT_ATTRIBUTES must be 0 or 1, #define FLEXT_ATTRIBUTES 1 // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif // define the class that stands for a pd/Max object class buffer1: // inherit from basic flext class public flext_base { // obligatory flext header (class name,base class name) featuring a setup function FLEXT_HEADER_S(buffer1,flext_base,setup) public: // constructor with a variable argument list buffer1(int argc,const t_atom *argv); protected: const t_symbol *bufname; buffer *buf; // set new buffer (or none if name omitted) void m_set(int argc,const t_atom *argv); // get buffer name void mg_buf(AtomList &lst) const; // set buffer name (simply reuse m_set method) inline void ms_buf(const AtomList &lst) { m_set(lst.Count(),lst.Atoms()); } // get buffer channels inline void mg_chns(int &chns) { chns = Check()?buf->Channels():0; } // get buffer length in frames inline void mg_frames(int &frames) { frames = Check()?buf->Frames():0; } // set buffer length in frames inline void ms_frames(int frames) { if(Check()) buf->Frames(frames); } // get sample (index channel) void m_peek(int argc,const t_atom *argv); // set sample (index value channel) void m_poke(int argc,const t_atom *argv); // delete eventual existing buffer void Clear(); // check and eventually update buffer reference (return true if valid) bool Check(); private: static void setup(t_classid c); FLEXT_CALLBACK_V(m_set) // wrapper for method m_set (with variable argument list) FLEXT_CALLBACK_V(m_peek) // wrapper for method m_peek (with variable argument list) FLEXT_CALLBACK_V(m_poke) // wrapper for method m_poke (with variable argument list) FLEXT_CALLVAR_V(mg_buf,ms_buf) // wrappers for attribute getter/setter mg_buffer/ms_buffer (with variable argument list) FLEXT_CALLGET_I(mg_chns) // wrappers for attribute getter mg_chns (with integer arguments) FLEXT_CALLVAR_I(mg_frames,ms_frames) // wrappers for attribute getter/setter mg_frames/ms_frames (with integer arguments) }; // instantiate the class FLEXT_NEW_V("buffer1",buffer1) void buffer1::setup(t_classid c) { // register methods and attributes FLEXT_CADDMETHOD_(c,0,"set",m_set); // register method "set" for inlet 0 FLEXT_CADDMETHOD_(c,0,"peek",m_peek); // register method "peek" for inlet 0 FLEXT_CADDMETHOD_(c,0,"poke",m_poke); // register method "poke" for inlet 0 FLEXT_CADDATTR_VAR(c,"buffer",mg_buf,ms_buf); // register attribute "buffer" FLEXT_CADDATTR_GET(c,"channels",mg_chns); // register attribute "channels" FLEXT_CADDATTR_VAR(c,"frames",mg_frames,ms_frames); // register attribute "frames" } buffer1::buffer1(int argc,const t_atom *argv): // clear buffer buf(NULL),bufname(NULL) { // define inlets: // first inlet must always be of type anything (or signal for dsp objects) AddInAnything("message inlet"); // add one inlet for any message // peek outlet AddOutFloat("peek value outlet"); // set buffer according to creation arguments m_set(argc,argv); } void buffer1::Clear() { if(buf) { delete buf; buf = NULL; bufname = NULL; } } bool buffer1::Check() { if(!buf || !buf->Valid()) { post("%s (%s) - no valid buffer defined",thisName(),GetString(thisTag())); // return zero length return false; } else { if(buf->Update()) { // buffer parameters have been updated if(buf->Valid()) { post("%s (%s) - updated buffer reference",thisName(),GetString(thisTag())); return true; } else { post("%s (%s) - buffer has become invalid",thisName(),GetString(thisTag())); return false; } } else return true; } } void buffer1::m_set(int argc,const t_atom *argv) { if(argc == 0) { // argument list is empty // clear existing buffer Clear(); } else if(argc == 1 && IsSymbol(argv[0])) { // one symbol given as argument // clear existing buffer Clear(); // save buffer name bufname = GetSymbol(argv[0]); // make new reference to system buffer object buf = new buffer(bufname); if(!buf->Ok()) { post("%s (%s) - warning: buffer is currently not valid!",thisName(),GetString(thisTag())); } } else { // invalid argument list, leave buffer as is but issue error message to console post("%s (%s) - message argument must be a symbol (or left blank)",thisName(),GetString(thisTag())); } } void buffer1::mg_buf(AtomList &lst) const { if(buf) { // buffer exists: return buffer name lst(1); SetSymbol(lst[0],bufname); } else // no buffer: set empty list lst(0); } void buffer1::m_poke(int argc,const t_atom *argv) { // if buffer is invalid bail out if(!Check()) return; bool ok = true; int ix,chn = 0; float val; if(argc == 3) { if(CanbeInt(argv[2])) // get channel index chn = GetAInt(argv[2]); else ok = false; } if(ok && (argc == 2 || argc == 3) && CanbeInt(argv[0]) && CanbeFloat(argv[1])) { // get frame index ix = GetAInt(argv[0]); // get value val = GetAFloat(argv[1]); } else ok = false; if(ok) { // correct syntax, set sample and trigger display (*buf)[ix] = val; buf->Dirty(true); } else post("%s (%s) - syntax error - use \"poke index value [channel]\"",thisName(),GetString(thisTag())); } void buffer1::m_peek(int argc,const t_atom *argv) { // if buffer is invalid bail out if(!Check()) return; bool ok = true; int ix,chn = 0; if(argc == 2) { if(CanbeInt(argv[1])) // get channel index chn = GetAInt(argv[1]); else ok = false; } if(ok && (argc == 1 || argc == 2) && CanbeInt(argv[0])) { // get frame index ix = GetAInt(argv[0]); } else ok = false; if(ok) // correct syntax, output value ToOutFloat(0,(*buf)[ix]); else post("%s (%s) - syntax error - use \"peek index [channel]\"",thisName(),GetString(thisTag())); } flext-0-6-3/tutorial/4_buffer1/package.txt000066400000000000000000000000351446466241400204250ustar00rootroot00000000000000NAME=buffer1 SRCS=main.cpp flext-0-6-3/tutorial/4_timer1/000077500000000000000000000000001446466241400161425ustar00rootroot00000000000000flext-0-6-3/tutorial/4_timer1/Makefile.am000066400000000000000000000000431446466241400201730ustar00rootroot00000000000000NAME = timer1 include ../common.mk flext-0-6-3/tutorial/4_timer1/main.cpp000066400000000000000000000062211446466241400175730ustar00rootroot00000000000000/* flext tutorial - timer 1 Copyright (c) 2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of an object using timers */ // enable flext attributes #define FLEXT_ATTRIBUTES 1 // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 403) #error You need at least flext version 0.4.3 #endif // define the class that stands for a pd/Max object class timer1: // inherit from basic flext class public flext_base { // obligatory flext header (class name,base class name) FLEXT_HEADER_S(timer1,flext_base,Setup) public: // constructor timer1(); protected: // timers Timer tmrA,tmrB; void m_getostime(float &f) { f = (float)GetOSTime(); } // method for operating system time attribute void m_getrttime(float &f) { f = (float)GetTime(); } // method for real-time system time attribute void m_timerA(void *) { ToOutString(0,"Timer A"); } // timer A method void m_timerB(void *) { ToOutString(0,"Timer B"); } // timer B method void m_resetA() { tmrA.Reset(); } // timer A reset void m_resetB() { tmrB.Reset(); } // timer B reset void m_oneshotA(int del) { tmrA.Delay(del*0.001); } // timer A one shot void m_oneshotB(int del) { tmrB.Delay(del*0.001); } // timer B one shot void m_periodicA(int del) { tmrA.Periodic(del*0.001); } // timer A periodic void m_periodicB(int del) { tmrB.Periodic(del*0.001); } // timer B periodic private: static void Setup(t_classid c); // register timer callbacks FLEXT_CALLBACK_T(m_timerA) FLEXT_CALLBACK_T(m_timerB) // register method callbacks FLEXT_CALLGET_F(m_getostime) FLEXT_CALLGET_F(m_getrttime) FLEXT_CALLBACK(m_resetA) FLEXT_CALLBACK(m_resetB) FLEXT_CALLBACK_I(m_oneshotA) FLEXT_CALLBACK_I(m_oneshotB) FLEXT_CALLBACK_I(m_periodicA) FLEXT_CALLBACK_I(m_periodicB) }; // instantiate the class FLEXT_NEW("timer1",timer1) // class setup function void timer1::Setup(t_classid c) { FLEXT_CADDATTR_GET(c,"ostime",m_getostime); // register attribute for OS time FLEXT_CADDATTR_GET(c,"time",m_getrttime); // register attribute for RT time FLEXT_CADDMETHOD_(c,0,"resetA",m_resetA); // register reset method for timer A FLEXT_CADDMETHOD_(c,0,"resetB",m_resetB); // register reset method for timer B FLEXT_CADDMETHOD_(c,0,"oneshotA",m_oneshotA); // register one shot method for timer A FLEXT_CADDMETHOD_(c,0,"oneshotB",m_oneshotB); // register one shot method for timer B FLEXT_CADDMETHOD_(c,0,"periodicA",m_periodicA); // register periodic method for timer A FLEXT_CADDMETHOD_(c,0,"periodicB",m_periodicB); // register periodic method for timer B } // class constructor timer1::timer1(): tmrA(false),tmrB(false) { AddInAnything("Control timers"); // add inlet for control commands AddOutAnything("Timer output"); // add outlet for timer output // register methods FLEXT_ADDTIMER(tmrA,m_timerA); // register method "m_timerA" for timer A FLEXT_ADDTIMER(tmrB,m_timerB); // register method "m_timerB" for timer B } flext-0-6-3/tutorial/4_timer1/package.txt000066400000000000000000000000341446466241400202730ustar00rootroot00000000000000NAME=timer1 SRCS=main.cpp flext-0-6-3/tutorial/5_signal1/000077500000000000000000000000001446466241400163005ustar00rootroot00000000000000flext-0-6-3/tutorial/5_signal1/Makefile.am000066400000000000000000000000451446466241400203330ustar00rootroot00000000000000NAME = signal1~ include ../common.mk flext-0-6-3/tutorial/5_signal1/main.cpp000066400000000000000000000106431446466241400177340ustar00rootroot00000000000000// signal1~ - a flext tutorial external written by Frank Barknecht // // This is a commented port of the pan~ example from the PD-Externals-Howto to // illustrate the usage of flext. You can get the original code at // http://iem.kug.ac.at/pd/externals-HOWTO/ #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401) #error You need at least flext version 0.4.1 #endif // A flext dsp external ("tilde object") inherits from the class flext_dsp class signal1: public flext_dsp { // Each external that is written in C++ needs to use #defines // from flbase.h // // The define // // FLEXT_HEADER(NEW_CLASS, PARENT_CLASS) // // should be somewhere in your dsp file. // A good place is here: FLEXT_HEADER(signal1, flext_dsp) public: signal1(): f_pan(0) // initialize f_pan { // The constructor of your class is responsible for // setting up inlets and outlets and for registering // inlet-methods: // The descriptions of the inlets and outlets are output // via the Max/MSP assist method (when mousing over them in edit mode). // PD will hopefully provide such a feature as well soon AddInSignal("left audio in"); // left audio in AddInSignal("right audio in"); // right audio in AddInFloat("panning parameter"); // 1 float in AddOutSignal("audio out"); // 1 audio out // Now we need to bind the handler function to our // panning inlet, which is inlet 2 (counting all inlets // from 0). We want the function "setPan" to get // called on incoming float messages: FLEXT_ADDMETHOD(2,setPan); // We're done constructing: post("-- pan~ with flext ---"); } // end of constructor protected: // here we declare the virtual DSP function virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); private: float f_pan; // holds our panning factor // Before we can use "setPan" as a handler, we must register this // function as a callback to PD or Max. This is done using the // FLEXT_CALLBACK* macros. There are several of them. // // FLEXT_CALLBACK_F is a shortcut, that registers a function // expecting one float arg (thus ending in "_F"). There are // other shortcuts that register other types of functions. Look // into flext.h. No semicolon at the end of line!!! FLEXT_CALLBACK_F(setPan) // Now setPan can get declared and defined here. void setPan(float f) { // set our private panning factor "f_pan" to the inlet // value float "f" in the intervall [0,1] f_pan = (f<0) ? 0.0f : (f>1) ? 1.0f : f ; // if you want to debug if this worked, comment out the // following line: //post("Set panning to %.2f, maybe clipped from %.2f", f_pan,f); } // end setPan }; // end of class declaration for signal1 // Before we can run our signal1-class in PD, the object has to be registered as a // PD object. Otherwise it would be a simple C++-class, and what good would // that be for? Registering is made easy with the FLEXT_NEW_* macros defined // in flext.h. For tilde objects without arguments call: FLEXT_NEW_DSP("signal1~ pan~", signal1) // T.Grill: there are two names for the object: signal1~ as main name and pan~ as its alias // Now we define our DSP function. It gets this arguments: // // int n: length of signal vector. Loop over this for your signal processing. // float *const *in, float *const *out: // These are arrays of the signals in the objects signal inlets rsp. // oulets. We come to that later inside the function. void signal1::m_signal(int n, t_sample *const *in, t_sample *const *out) { const t_sample *ins1 = in[0]; const t_sample *ins2 = in[1]; // As said above "in" holds a list of the signal vectors in all inlets. // After these two lines, ins1 holds the signal vector ofthe first // inlet, index 0, and ins2 holds the signal vector of the second // inlet, with index 1. t_sample *outs = out[0]; // Now outs holds the signal vector at the one signal outlet we have. // We are now ready for the main signal loop while (n--) { // The "++" after the pointers outs, ins1 and ins2 walks us // through the signal vector with each n, of course. Before // each step we change the signal value in the outlet *outs // according to our panning factor "f_pan" and according to the // signals at the two signal inlets, *ins1 and *ins2 *outs++ = (*ins1++) * (1-f_pan) + (*ins2++) * f_pan; } } // end m_signal flext-0-6-3/tutorial/5_signal1/package.txt000066400000000000000000000000361446466241400204330ustar00rootroot00000000000000NAME=signal1~ SRCS=main.cpp flext-0-6-3/tutorial/5_signal2/000077500000000000000000000000001446466241400163015ustar00rootroot00000000000000flext-0-6-3/tutorial/5_signal2/Makefile.am000066400000000000000000000000451446466241400203340ustar00rootroot00000000000000NAME = signal2~ include ../common.mk flext-0-6-3/tutorial/5_signal2/main.cpp000066400000000000000000000030371446466241400177340ustar00rootroot00000000000000/* flext tutorial - signal 2 Copyright (c) 2002-2022 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an object showing varous parameters of the pd audio system */ // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif // define the class that stands for a pd/Max object // Attention: the class name must be the same as the object name!! (without the ~) class signal2: // inherit from flext dsp class public flext_dsp { // obligatory flext header (class name,base class name) FLEXT_HEADER(signal2,flext_dsp) public: // constructor signal2(); protected: void m_bang(); // method for bang private: FLEXT_CALLBACK(m_bang) // callback for method "m_bang" }; // instantiate the class FLEXT_NEW_DSP("signal2~",signal2) signal2::signal2() { // define inlets: // first inlet must always by of type anything (or signal for dsp objects) AddInAnything(); // add one inlet for any message // add outlets for sample rate and block size AddOutFloat(1); AddOutInt(1); // register methods FLEXT_ADDBANG(0,m_bang); // register method "m_bang" for bang message into inlet 0 } void signal2::m_bang() { // output various parameters of the audio system ToOutFloat(0,Samplerate()); ToOutInt(1,Blocksize()); } flext-0-6-3/tutorial/5_signal2/package.txt000066400000000000000000000000361446466241400204340ustar00rootroot00000000000000NAME=signal2~ SRCS=main.cpp flext-0-6-3/tutorial/6_lib1/000077500000000000000000000000001446466241400155725ustar00rootroot00000000000000flext-0-6-3/tutorial/6_lib1/Makefile.am000066400000000000000000000000411446466241400176210ustar00rootroot00000000000000NAME = lib1 include ../common.mk flext-0-6-3/tutorial/6_lib1/main.cpp000066400000000000000000000061621446466241400172270ustar00rootroot00000000000000/* flext tutorial - library 1 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of an external library containing a few simple objects It uses attributes, so be sure that you've already worked through attr1 and attr2 */ // Enable attribute processing // For clarity, this is done here, but you'd better specify it as a compiler definition #define FLEXT_ATTRIBUTES 1 // include flext header #include // check for appropriate flext version #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif // ------------------------------------------------------------------------------------- // Define the base class // Note that you don't have to instantiate the base class (with FLEXT_NEW or variants) class libbase: // inherit from basic flext class public flext_base { // obligatory flext header (class name,base class name) FLEXT_HEADER(libbase,flext_base) public: // constructor libbase(); protected: void Output(float f) const { ToOutFloat(0,f); } // method for floats into left inlet virtual void m_trigger(float f) = 0; float arg; // argument variable private: FLEXT_CALLBACK_F(m_trigger) // callback for method "m_trigger" (with one float argument) FLEXT_ATTRVAR_F(arg) }; libbase::libbase(): arg(0) // initialize argument { // define inlets: // first inlet must always by of type anything (or signal for dsp objects) AddInAnything(); // add one inlet for any message // define outlets: AddOutFloat(); // add one float outlet (has index 0) // register methods FLEXT_ADDMETHOD(0,m_trigger); // register method (for float messages) "m_float" for inlet 0 // register attributes FLEXT_ADDATTR_VAR1("arg",arg); // register attribute "arg" } // ------------------------------------------------------------------ // Define the actual library objects (derived from the base class) // These classes have an implementation of the virtual function m_trigger class libadd: public libbase { // obligatory flext header, inherit from libbase FLEXT_HEADER(libadd,libbase) public: virtual void m_trigger(float f) { Output(f+arg); } }; FLEXT_LIB("lib1.+",libadd); class libsub: public libbase { // obligatory flext header, inherit from libbase FLEXT_HEADER(libsub,libbase) public: virtual void m_trigger(float f) { Output(f-arg); } }; FLEXT_LIB("lib1.-",libsub); class libmul: public libbase { // obligatory flext header, inherit from libbase FLEXT_HEADER(libmul,libbase) public: virtual void m_trigger(float f) { Output(f*arg); } }; FLEXT_LIB("lib1.*",libmul); // ------------------------------------------------ // Do the library setup static void lib_setup() { post("flext tutorial lib1, (C)2002 Thomas Grill"); post("lib1: lib1.+ lib1.- lib1.*"); post(""); // call the objects' setup routines FLEXT_SETUP(libadd); FLEXT_SETUP(libsub); FLEXT_SETUP(libmul); } // setup the library FLEXT_LIB_SETUP(lib1,lib_setup) flext-0-6-3/tutorial/6_lib1/package.txt000066400000000000000000000000321446466241400177210ustar00rootroot00000000000000NAME=lib1 SRCS=main.cpp flext-0-6-3/tutorial/7_thread1/000077500000000000000000000000001446466241400162745ustar00rootroot00000000000000flext-0-6-3/tutorial/7_thread1/Makefile.am000066400000000000000000000000441446466241400203260ustar00rootroot00000000000000NAME = thread1 include ../common.mk flext-0-6-3/tutorial/7_thread1/main.cpp000066400000000000000000000036041446466241400177270ustar00rootroot00000000000000/* flext tutorial - threads 1 Copyright (c) 2002,2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This shows an example of a method running as a thread */ /* define FLEXT_THREADS for thread usage. Flext must also have been compiled with that defined! it's even better to define that as a compiler flag (-D FLEXT_THREADS) for all files of the flext external */ #ifndef FLEXT_THREADS #define FLEXT_THREADS #endif #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif class thread1: public flext_base { FLEXT_HEADER(thread1,flext_base) public: thread1(); protected: void m_start(); // method function private: // define threaded callback for method m_start // the same syntax as with FLEXT_CALLBACK is used here FLEXT_THREAD(m_start) }; FLEXT_NEW("thread1",thread1) thread1::thread1() { AddInAnything(); AddOutInt(); FLEXT_ADDBANG(0,m_start); // register method } void thread1::m_start() { // Please note that this functions needs about 10 seconds to complete // Without threads it would block the real-time system // Okay, that functionality would be far more elegant with timers // ... but hey, it's a demo! for(int i = 0; i < 20 && !ShouldExit(); ++i) { ToOutInt(0,i); // output loop count // post("%i",i); // wait for half a second for(int j = 0; j < 5 && !ShouldExit(); ++j) Sleep(0.1f); // note: we shall not block a thread for a longer time. // The system might want to destroy the object in the meantime and // expects thread termination. In such a case flext waits // for 1 second by default, then it aborts the thread brutally } // output a final zero ToOutInt(0,0); // post("end"); } flext-0-6-3/tutorial/7_thread1/package.txt000066400000000000000000000000561446466241400204310ustar00rootroot00000000000000NAME=thread1 BUILDTYPE=multi SRCS=main.cpp flext-0-6-3/tutorial/7_thread2/000077500000000000000000000000001446466241400162755ustar00rootroot00000000000000flext-0-6-3/tutorial/7_thread2/Makefile.am000066400000000000000000000000441446466241400203270ustar00rootroot00000000000000NAME = thread2 include ../common.mk flext-0-6-3/tutorial/7_thread2/main.cpp000066400000000000000000000057371446466241400177410ustar00rootroot00000000000000/* flext tutorial - threads 2 Copyright (c) 2002-2022 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This shows an example of multiple threads and syncing with a thread conditional */ /* define FLEXT_THREADS for thread usage. Flext must also have been compiled with that defined! it's even better to define that as a compiler flag (-D FLEXT_THREADS) for all files of the flext external */ #ifndef FLEXT_THREADS #define FLEXT_THREADS #endif #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 400) #error You need at least flext version 0.4.0 #endif class thread2: public flext_base { FLEXT_HEADER(thread2,flext_base) public: thread2(int del); protected: void m_start(int st); void m_stop(); void m_text(); void m_textout(); private: FLEXT_THREAD_I(m_start) // define threaded callback for method m_start FLEXT_CALLBACK(m_stop) // normal callback for m_stop FLEXT_CALLBACK(m_text) // turn on console output FLEXT_THREAD(m_textout) // text output float delay; volatile int count; // caution: CodeWarrior seems to ignore volatile modifier!! volatile bool stopit,running,blipping; // flags for running and stopping // thread conditional for stop signal ThrCond cond; }; FLEXT_NEW_1("thread2",thread2,int) thread2::thread2(int del): delay(del/1000.f), stopit(false), running(false),blipping(false) { AddInAnything(); AddOutInt(2); FLEXT_ADDMETHOD(0,m_start); // register start for integer numbers (floats in PD) FLEXT_ADDMETHOD_(0,"text",m_text); // register m_text method for "text" tag FLEXT_ADDMETHOD_(0,"stop",m_stop); // register m_text method for "stop" tag } void thread2::m_start(int st) { // if already running, just set back the counter if(running) { count = st; return; } running = true; // loop until either the system exit flag or the "stopit" flag is set for(count = st; !ShouldExit() && !stopit; ++count) { Sleep(delay); ToOutInt(0,count); // output loop count } running = false; // change state flag // cond.Lock(); // lock conditional cond.Signal(); // signal changed flag to waiting "stop" method // cond.Unlock(); // unlock conditional } void thread2::m_stop() { // cond.Lock(); // lock conditional stopit = true; // set termination flag while(running || blipping) { cond.Wait(); // wait for signal by running threads } // --- Here, the threads should have stopped --- stopit = false; // reset flag // cond.Unlock(); // unlock conditional } void thread2::m_text() { FLEXT_CALLMETHOD(m_textout); } void thread2::m_textout() { if(blipping) return; blipping = true; while(!ShouldExit() && !stopit) { post("%i",count); Sleep(1.f); } blipping = false; // change state flag // cond.Lock(); // lock conditional cond.Signal(); // signal changed flag to waiting "stop" method // cond.Unlock(); // unlock conditional } flext-0-6-3/tutorial/7_thread2/package.txt000066400000000000000000000000561446466241400204320ustar00rootroot00000000000000NAME=thread2 BUILDTYPE=multi SRCS=main.cpp flext-0-6-3/tutorial/8_sndobj1/000077500000000000000000000000001446466241400163055ustar00rootroot00000000000000flext-0-6-3/tutorial/8_sndobj1/Makefile.am000066400000000000000000000000441446466241400203370ustar00rootroot00000000000000NAME = sndobj1 include ../common.mk flext-0-6-3/tutorial/8_sndobj1/main.cpp000066400000000000000000000036011446466241400177350ustar00rootroot00000000000000/* flext tutorial - sndobj 1 Copyright (c) 2002-2006 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of an external using the SndObj library. See http://www.may.ie/academic/music/musictec/SndObj/ The SndObj library should be compiled multithreaded. This external features simple stereo pitch shifting. */ #define FLEXT_ATTRIBUTES 1 #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401) #error You need at least flext version 0.4.1 with sndobj support #endif class sndobj1: public flext_sndobj { FLEXT_HEADER_S(sndobj1,flext_sndobj,Setup) public: sndobj1(); // these are obligatory! virtual bool NewObjs(); virtual void FreeObjs(); virtual void ProcessObjs(); // space for a few sndobjs Pitch *obj1,*obj2; float sh1,sh2; private: static void Setup(t_classid c); FLEXT_ATTRVAR_F(sh1) FLEXT_ATTRVAR_F(sh2) }; FLEXT_NEW_DSP("sndobj1~",sndobj1) sndobj1::sndobj1(): sh1(1),sh2(1), obj1(NULL),obj2(NULL) { AddInSignal(2); // audio ins AddOutSignal(2); // audio outs } void sndobj1::Setup(t_classid c) { FLEXT_CADDATTR_VAR1(c,"shL",sh1); FLEXT_CADDATTR_VAR1(c,"shR",sh2); } // construct needed SndObjs bool sndobj1::NewObjs() { // set up objects obj1 = new Pitch(.1f,&InObj(0),sh1,Blocksize(),Samplerate()); obj2 = new Pitch(.1f,&InObj(1),sh2,Blocksize(),Samplerate()); return true; } // destroy the SndObjs void sndobj1::FreeObjs() { if(obj1) delete obj1; if(obj2) delete obj2; } // this is called on every DSP block void sndobj1::ProcessObjs() { // set current pitch shift obj1->SetPitch(sh1); obj2->SetPitch(sh2); // do processing here!! obj1->DoProcess(); obj2->DoProcess(); // output *obj1 >> OutObj(0); *obj2 >> OutObj(1); } flext-0-6-3/tutorial/8_sndobj1/package.txt000066400000000000000000000000361446466241400204400ustar00rootroot00000000000000NAME=sndobj1~ SRCS=main.cpp flext-0-6-3/tutorial/8_stk1/000077500000000000000000000000001446466241400156275ustar00rootroot00000000000000flext-0-6-3/tutorial/8_stk1/Makefile.am000066400000000000000000000000411446466241400176560ustar00rootroot00000000000000NAME = stk1 include ../common.mk flext-0-6-3/tutorial/8_stk1/main.cpp000066400000000000000000000034041446466241400172600ustar00rootroot00000000000000/* flext tutorial - stk 1 Copyright (c) 2002-2010 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of an external using the STK ("synthesis toolkit") library. For STK see http://ccrma-www.stanford.edu/software/stk STK needs C++ exceptions switched on. The STK tutorial examples assume that a static stk library exists which contains all the source files (except rt*.cpp) of the stk/src directory. The library should be compiled multithreaded and with the appropriate compiler flags for the respective platform (e.g. __OS_WINDOWS__ and __LITTLE_ENDIAN__ for Windows) */ #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401) #error You need at least flext version 0.4.1 with STK support #endif #include "Noise.h" using namespace stk; class stk1: public flext_stk { FLEXT_HEADER(stk1,flext_stk) public: stk1(); protected: // these are obligatory! virtual bool NewObjs(); // create STK instruments virtual void FreeObjs(); // destroy STK instruments virtual void ProcessObjs(int n); // do DSP processing private: Noise *inst; }; FLEXT_NEW_DSP("stk1~",stk1) stk1::stk1(): inst(NULL) { AddInAnything(); AddOutSignal(); } // create STK instruments bool stk1::NewObjs() { bool ok = true; // set up objects try { inst = new Noise; } catch (StkError &) { post("%s - Noise() setup failed!",thisName()); ok = false; } return ok; } // destroy the STK instruments void stk1::FreeObjs() { if(inst) delete inst; } // this is called on every DSP block void stk1::ProcessObjs(int n) { while(n--) Outlet(0).tick(inst->tick()); } flext-0-6-3/tutorial/8_stk1/package.txt000066400000000000000000000000331446466241400177570ustar00rootroot00000000000000NAME=stk1~ SRCS=main.cpp flext-0-6-3/tutorial/8_stk2/000077500000000000000000000000001446466241400156305ustar00rootroot00000000000000flext-0-6-3/tutorial/8_stk2/Makefile.am000066400000000000000000000000411446466241400176570ustar00rootroot00000000000000NAME = stk2 include ../common.mk flext-0-6-3/tutorial/8_stk2/main.cpp000066400000000000000000000045041446466241400172630ustar00rootroot00000000000000/* flext tutorial - stk 2 Copyright (c) 2002-2010 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ------------------------------------------------------------------------- This is an example of an external using the STK ("synthesis toolkit") library. For STK see http://ccrma-www.stanford.edu/software/stk STK needs C++ exceptions switched on. The STK tutorial examples assume that a static stk library exists which contains all the source files (except rt*.cpp) of the stk/src directory. The library should be compiled multithreaded and with the appropriate compiler flags for the respective platform (e.g. __OS_WINDOWS__ and __LITTLE_ENDIAN__ for Windows) */ #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401) #error You need at least flext version 0.4.1 with STK support #endif #include "PitShift.h" using namespace stk; class stk2: public flext_stk { FLEXT_HEADER_S(stk2,flext_stk,Setup) public: stk2(); void m_sh1(float f) { if(inst[0]) inst[0]->setShift(f); } void m_sh2(float f) { if(inst[1]) inst[1]->setShift(f); } // these are obligatory! virtual bool NewObjs(); // create STK instruments virtual void FreeObjs(); // destroy STK instruments virtual void ProcessObjs(int n); // do DSP processing PitShift *inst[2]; StkFrames vec; private: static void Setup(t_classid c); FLEXT_CALLBACK_F(m_sh1) FLEXT_CALLBACK_F(m_sh2) }; FLEXT_NEW_DSP("stk2~",stk2) stk2::stk2() { AddInSignal(); AddOutSignal(2); inst[0] = inst[1] = NULL; } void stk2::Setup(t_classid c) { FLEXT_CADDMETHOD_F(c,0,"shL",m_sh1); FLEXT_CADDMETHOD_F(c,0,"shR",m_sh2); } // create STK instruments bool stk2::NewObjs() { bool ok = true; try { // set up objects for(int i = 0; i < 2; ++i) inst[i] = new PitShift; // reserve one signal vector too vec.resize(Blocksize()); } catch (StkError &) { post("%s - Creation failed!",thisName()); ok = false; } return ok; } // destroy the STK instruments void stk2::FreeObjs() { for(int i = 0; i < 2; ++i) if(inst[i]) delete inst[i]; } // this is called on every DSP block void stk2::ProcessObjs(int n) { for(int i = 0; i < 2; ++i) { Inlet(0).tick(vec); inst[i]->tick(vec); Outlet(i).tick(vec); } } flext-0-6-3/tutorial/8_stk2/package.txt000066400000000000000000000000331446466241400177600ustar00rootroot00000000000000NAME=stk2~ SRCS=main.cpp flext-0-6-3/tutorial/Makefile.am000066400000000000000000000011751446466241400165560ustar00rootroot00000000000000# # automake template # added by tim blechmann # SUBDIRS = \ 1_simple1 \ 1_simple2 \ 1_simple3 \ 2_adv1 \ 2_adv2 \ 2_adv3 \ 3_attr1 \ 3_attr2 \ 3_attr3 \ 4_bind1 \ 4_buffer1 \ 4_timer1 \ 5_signal1 \ 5_signal2 \ 6_lib1 \ 7_thread1 \ 7_thread2 \ pd \ maxmsp # 8_sndobj1 \ # 8_stk1 \ # 8_stk2 \ # EXTRA_DIST = \ readme.txt \ gpl.txt DIST_SUBDIRS = pd \ maxmsp \ 1_simple1 \ 1_simple2 \ 1_simple3 \ 2_adv1 \ 2_adv2 \ 2_adv3 \ 3_attr1 \ 3_attr2 \ 3_attr3 \ 4_bind1 \ 4_buffer1 \ 4_timer1 \ 5_signal1 \ 5_signal2 \ 6_lib1 \ 7_thread1 \ 7_thread2 \ pd \ maxmsp # 8_sndobj1 \ # 8_stk1 \ # 8_stk2 \ #flext-0-6-3/tutorial/build.bat000066400000000000000000000012501446466241400163030ustar00rootroot00000000000000@echo off if "%1"=="" goto syntax if "%2"=="" goto syntax rem first check configuration call ..\build.bat %1 %2 config "PKGINFO=" "NAME=tutorial" "SRCS=." if errorlevel 1 goto end for /D %%i in (*) do ( pushd %%i if exist package.txt ( call ..\..\build.bat %1 %2 ) popd ) goto end rem ----------------------------------------- :syntax echo . echo SYNTAX: build [system] [compiler] echo system ... pd / max echo compiler ... msvc / gcc / mingw / cygwin echo . echo Please make sure that your make program and compiler can be accessed with the echo system path and that all relevant environment variables are properly set. echo . :end flext-0-6-3/tutorial/build.sh000077500000000000000000000025141446466241400161560ustar00rootroot00000000000000#! /bin/bash if [ -n "$1" -a -n "$2" ] then # make config first if bash ../build.sh $1 $2 config "PKGINFO=" "NAME=tutorial" "SRCS=\"\"" then success=1 # iterate through tutorial categories 1...8 for c in `seq 1 8`; do for i in ${c}_* ; do if [ -e $i/package.txt ] ; then pushd $i if bash ../../build.sh $1 $2 then true # we are ok! else # category 8 doesn't count, but other compilations need to succeed if [ $c -lt 8 ]; then success=0; fi fi popd fi done done if [ $success -ne 0 ]; then ok=0 else echo Compilation failed ok=-3 fi else echo Config failed ok=-2 fi else echo echo SYNTAX: build.sh [platform] [system] [compiler] echo system ..... pd / max echo compiler ... msvc / gcc / mingw / cygwin echo echo Please make sure that your make program and compiler can be accessed with the echo system path and that all relevant environment variables are properly set. echo ok=-1 fi exit $ok flext-0-6-3/tutorial/common.mk000066400000000000000000000016151446466241400163420ustar00rootroot00000000000000# # automake template # # added by tim blechmann # modified by grrrr.org # # this is being included by subfolder Makefiles BUILT_SOURCES = main.cpp CXXFLAGS = @CXXFLAGS@ \ @OPT_FLAGS@ \ $(patsubst %,-I%,@INCLUDEDIRS@) \ -I@top_srcdir@/source \ -D FLEXT_INLINE=1 \ $(DEFS) \ -DFLEXT_SHARED LDFLAGS = @LD_FLAGS@ $(patsubst %,-L%,@LIBDIRS@) $(patsubst %,-framework %,$(FRAMEWORKS)) FRAMEWORKS = @FRAMEWORKS@ TARGET = $(NAME).@EXTENSION@ OBJECTS = $(patsubst %.cpp,./%.@OBJEXT@,$(BUILT_SOURCES)) EXTDIR = @EXTDIR@ # ----------------------------- targets -------------------------------- all-local: $(OBJECTS) $(CXX) $(LDFLAGS) ./*.@OBJEXT@ $(LIBS) -o ./$(TARGET) ./%.@OBJEXT@ : %.cpp $(CXX) -c $(CXXFLAGS) $< -o $@ clean-local: rm -f ./$(TARGET) rm -f ./$(OBJECTS) install-exec-local: $(MKDIR_P) "$(DESTDIR)$(EXTDIR)" $(INSTALL_STRIP_PROGRAM) -m 644 ./$(TARGET) $(DESTDIR)$(EXTDIR) flext-0-6-3/tutorial/gpl.txt000066400000000000000000000431311446466241400160430ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. flext-0-6-3/tutorial/license.txt000066400000000000000000000037301446466241400167040ustar00rootroot00000000000000flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (C) 2001-2006 Thomas Grill This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. In the official flext distribution, the GNU General Public License is in the file gpl.txt --------------------------------------------------------- OTHER COPYRIGHT NOTICES --------------------------------------------------------- This package uses a lot of code from GEM by Mark Danks See the license text below: --- GEM -------------------------------------- GEM - Graphics Environment for Multimedia Copyright (C) 1997-2000 Mark Danks This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. In the official GEM distribution, the GNU General Public License is in the file GnuGPL.LICENSE flext-0-6-3/tutorial/maxmsp/000077500000000000000000000000001446466241400160235ustar00rootroot00000000000000flext-0-6-3/tutorial/maxmsp/Makefile.am000066400000000000000000000000001446466241400200450ustar00rootroot00000000000000flext-0-6-3/tutorial/maxmsp/ex-adv1.maxpat000066400000000000000000000104561446466241400205120ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 34.0, 97.0, 553.0, 282.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 198.0, 199.0, 61.0, 20.0 ], "text" : "prepend set" } } , { "box" : { "bgcolor" : [ 0.866666666666667, 0.866666666666667, 0.866666666666667, 1.0 ], "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 213.0, 113.0, 35.0, 20.0 ], "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ], "triscale" : 0.9 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-3", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 280.0, 103.0, 23.0, 20.0 ], "text" : "2 3" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-4", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 192.0, 92.0, 69.0, 20.0 ], "text" : "or two words" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 198.0, 220.0, 183.0, 20.0 ], "text" : "one 2 3" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-7", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 198.0, 159.0, 90.0, 23.0 ], "text" : "adv1 one" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-8", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 24.0, 16.0, 100.0, 47.0 ], "text" : "adv1" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-9", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 181.0, 27.5, 339.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-10", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 14.0, 14.0, 524.0, 49.0 ], "rounded" : 0 } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-6", 0 ], "source" : [ "obj-1", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 0 ], "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 0 ], "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 0 ], "source" : [ "obj-4", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-7", 0 ] } } ], "dependency_cache" : [ ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-adv2.maxpat000066400000000000000000000135321446466241400205110ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 186.0, 190.0, 581.0, 297.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-2", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 27.0, 16.0, 108.0, 47.0 ], "text" : "adv2" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 190.0, 29.5, 341.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-4", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 19.0, 16.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 324.0, 195.0, 100.0, 18.0 ], "text" : "other symbol" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 283.0, 193.0, 29.0, 20.0 ], "text" : "yeah" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-7", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 325.0, 173.0, 100.0, 18.0 ], "text" : "tag and argument" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 284.0, 171.0, 35.0, 20.0 ], "text" : "hula 1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 269.0, 140.0, 26.0, 20.0 ], "text" : "hula" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 246.0, 140.0, 18.0, 20.0 ], "text" : "to" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-11", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 215.0, 140.0, 28.0, 20.0 ], "text" : "born" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 10.0, "id" : "obj-12", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 125.0, 109.0, 28.0, 21.0 ], "text" : "help" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-13", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 215.0, 247.0, 38.0, 23.0 ], "text" : "adv2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 156.0, 112.0, 100.0, 18.0 ], "text" : "issue help message" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-15", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 306.0, 141.0, 104.0, 18.0 ], "text" : "tag without argument" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-16", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 29.0, 70.0, 370.0, 21.0 ], "text" : "this is identical with the simple3 example" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-adv3.maxpat000066400000000000000000000171361446466241400205160ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 111.0, 137.0, 565.0, 312.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-23", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 227.0, 252.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-12", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 184.0, 114.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-1", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 122.0, 107.0, 21.0, 21.0 ] } } , { "box" : { "id" : "obj-2", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 281.0, 252.0, 21.0, 21.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-4", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 394.0, 110.0, 16.0, 20.0 ], "text" : "2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 371.0, 110.0, 19.0, 20.0 ], "text" : "-1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 352.0, 110.0, 16.0, 20.0 ], "text" : "1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-7", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 353.0, 88.0, 72.0, 18.0 ], "text" : "set step size" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 300.0, 110.0, 23.0, 20.0 ], "text" : "7 2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 262.0, 110.0, 30.0, 20.0 ], "text" : "1 10" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 184.0, 138.0, 38.0, 20.0 ], "text" : "set $1" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-13", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 29.0, 16.0, 108.0, 47.0 ], "text" : "adv3" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-14", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 193.0, 29.5, 341.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "angle" : 0.0, "bgcolor" : [ 0.878431, 0.6, 0.352941, 1.0 ], "id" : "obj-15", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 19.0, 16.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 10.0, "id" : "obj-16", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 118.0, 183.0, 34.0, 21.0 ], "text" : "reset" } } , { "box" : { "color" : [ 1.0, 0.360784, 0.682353, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-17", "maxclass" : "newobj", "numinlets" : 3, "numoutlets" : 2, "outlettype" : [ "int", "symbol" ], "patching_rect" : [ 241.0, 217.0, 47.0, 23.0 ], "text" : "adv3" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-18", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 118.0, 165.0, 38.0, 18.0 ], "text" : "reset" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-19", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 114.0, 89.0, 43.0, 18.0 ], "text" : "trigger" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-20", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 180.0, 88.0, 68.0, 18.0 ], "text" : "set counter" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-21", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 263.0, 88.0, 67.0, 18.0 ], "text" : "set bounds" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-17", 0 ], "source" : [ "obj-1", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 0 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-10", 0 ], "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 0 ], "source" : [ "obj-16", 0 ] } } , { "patchline" : { "destination" : [ "obj-2", 0 ], "source" : [ "obj-17", 1 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 2 ], "source" : [ "obj-4", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 2 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 2 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 1 ], "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 1 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "adv3.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-attr1.maxpat000066400000000000000000000156641446466241400207200ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 95.0, 119.0, 581.0, 352.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "annotation" : "", "hint" : "", "id" : "obj-25", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 89.0, 127.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-23", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 180.0, 276.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-16", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 229.0, 164.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 276.5, 188.0, 105.0, 18.0 ], "text" : "set attribute \"arg\"" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 268.0, 135.0, 196.0, 18.0 ], "text" : "query attribute \"arg\" (watch console)" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 296.0, 108.0, 196.0, 18.0 ], "text" : "query object attributes (watch console)" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 229.0, 188.0, 38.0, 20.0 ], "text" : "arg $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-7", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 229.0, 134.0, 37.0, 20.0 ], "text" : "getarg" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 229.0, 107.0, 66.0, 20.0 ], "text" : "getattributes" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 89.0, 107.0, 71.0, 18.0 ], "text" : "trigger output" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-12", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 257.0, 298.0, 231.0, 18.0 ], "text" : "additional outlet for all attribute-enabled objects" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 257.0, 276.0, 30.0, 20.0 ], "text" : "print" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-15", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "float", "" ], "patching_rect" : [ 180.0, 241.0, 96.0, 23.0 ], "text" : "attr1 @arg 3" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-17", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 30.0, 17.0, 123.0, 47.0 ], "text" : "attr1" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-18", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 196.0, 29.5, 340.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-19", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 22.0, 16.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-20", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 180.0, 298.0, 47.0, 18.0 ], "text" : "result" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-21", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 221.0, 227.0, 138.0, 18.0 ], "text" : "attribute as a creation arg" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-14", 0 ], "source" : [ "obj-15", 1 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-15", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 0 ], "source" : [ "obj-16", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "source" : [ "obj-25", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "midpoints" : [ 238.5, 155.0, 189.5, 155.0 ], "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "midpoints" : [ 238.5, 133.0, 189.5, 133.0 ], "source" : [ "obj-8", 0 ] } } ], "dependency_cache" : [ { "name" : "attr1.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-attr2.maxpat000066400000000000000000000250271446466241400207130ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 109.0, 163.0, 621.0, 349.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-33", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 109.0, 170.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-31", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 242.0, 276.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-25", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 102.0, 258.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 382.0, 173.0, 105.0, 18.0 ], "text" : "set attribute \"op\"" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 342.0, 183.0, 35.0, 20.0 ], "text" : "op **" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-3", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 342.0, 161.0, 28.0, 20.0 ], "text" : "op =" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-4", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 308.0, 183.0, 27.0, 20.0 ], "text" : "op /" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 308.0, 161.0, 28.0, 20.0 ], "text" : "op *" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 275.0, 183.0, 26.0, 20.0 ], "text" : "op -" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-7", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 275.0, 161.0, 28.0, 20.0 ], "text" : "op +" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 188.0, 128.0, 49.0, 20.0 ], "text" : "getresult" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 151.0, 128.0, 34.0, 20.0 ], "text" : "getop" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 149.0, 195.0, 105.0, 18.0 ], "text" : "set attribute \"arg\"" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-11", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 242.0, 129.0, 86.0, 18.0 ], "text" : "query attributes" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-12", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 181.0, 95.0, 196.0, 18.0 ], "text" : "query object attributes (watch console)" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 109.0, 195.0, 38.0, 20.0 ], "text" : "arg $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-16", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 111.0, 128.0, 37.0, 20.0 ], "text" : "getarg" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-17", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 113.0, 95.0, 66.0, 20.0 ], "text" : "getattributes" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-19", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 102.0, 238.0, 71.0, 18.0 ], "text" : "trigger output" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-21", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 303.0, 302.0, 275.0, 18.0 ], "text" : "additional outlet for all attribute-enabled objects" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-23", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 303.0, 278.0, 30.0, 20.0 ], "text" : "print" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-24", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "float", "" ], "patching_rect" : [ 242.0, 246.0, 80.0, 23.0 ], "text" : "attr2 @op +" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-26", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 31.0, 16.0, 142.0, 47.0 ], "text" : "attr2" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-27", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 198.0, 29.5, 342.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-28", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 22.0, 16.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-29", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 242.0, 302.0, 47.0, 18.0 ], "text" : "result" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 118.5, 225.0, 251.5, 225.0 ], "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 120.5, 157.0, 251.5, 157.0 ], "source" : [ "obj-16", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 122.5, 127.0, 98.0, 127.0, 98.0, 157.0, 251.5, 157.0 ], "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 351.5, 202.0, 251.5, 202.0 ], "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-24", 1 ] } } , { "patchline" : { "destination" : [ "obj-31", 0 ], "source" : [ "obj-24", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 111.5, 290.0, 181.5, 290.0, 181.5, 225.0, 251.5, 225.0 ], "source" : [ "obj-25", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 351.5, 180.0, 251.5, 180.0 ], "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-14", 0 ], "source" : [ "obj-33", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 317.5, 202.0, 251.5, 202.0 ], "source" : [ "obj-4", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 317.5, 180.0, 251.5, 180.0 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 284.5, 202.0, 251.5, 202.0 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 284.5, 180.0, 251.5, 180.0 ], "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 197.5, 157.0, 251.5, 157.0 ], "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "midpoints" : [ 160.5, 157.0, 251.5, 157.0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "attr2.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-attr3.maxpat000066400000000000000000000314061446466241400207120ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 92.0, 150.0, 581.0, 352.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-9", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 311.0, 265.0, 72.0, 22.0 ], "text" : "prepend set" } } , { "box" : { "id" : "obj-33", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 182.0, 289.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-27", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 190.0, 111.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 358.0, 181.0, 37.0, 20.0 ], "text" : "step 3" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 358.0, 161.0, 42.0, 20.0 ], "text" : "getstep" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-3", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 264.0, 182.0, 64.0, 20.0 ], "text" : "bounds 5 15" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-4", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 264.0, 162.0, 55.0, 20.0 ], "text" : "getbounds" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 61.0, 212.0, 42.0, 20.0 ], "text" : "count 3" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 61.0, 186.0, 48.0, 20.0 ], "text" : "getcount" } } , { "box" : { "bgcolor" : [ 1.0, 0.611764705882353, 0.611764705882353, 1.0 ], "bgcolor2" : [ 1.0, 0.611764705882353, 0.611764705882353, 1.0 ], "bgfillcolor_angle" : 270.0, "bgfillcolor_autogradient" : 0.0, "bgfillcolor_color" : [ 0.2, 0.2, 0.2, 1.0 ], "bgfillcolor_color1" : [ 1.0, 0.611764705882353, 0.611764705882353, 1.0 ], "bgfillcolor_color2" : [ 0.0, 0.0, 0.0, 1.0 ], "bgfillcolor_proportion" : 0.5, "bgfillcolor_type" : "color", "fontname" : "Geneva", "fontsize" : 9.0, "gradient" : 1, "id" : "obj-7", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 61.0, 162.0, 68.0, 20.0 ], "text" : "getattributes" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 311.0, 289.0, 196.0, 20.0 ] } } , { "box" : { "id" : "obj-10", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 68.0, 111.0, 21.0, 21.0 ] } } , { "box" : { "id" : "obj-11", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 264.0, 289.0, 21.0, 21.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-13", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 401.0, 110.0, 16.0, 20.0 ], "text" : "2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 378.0, 110.0, 19.0, 20.0 ], "text" : "-1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-15", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 359.0, 110.0, 16.0, 20.0 ], "text" : "1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-16", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 360.0, 91.0, 72.0, 18.0 ], "text" : "set step size" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-17", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 307.0, 110.0, 23.0, 20.0 ], "text" : "7 2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-18", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 269.0, 110.0, 30.0, 20.0 ], "text" : "1 10" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-19", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 190.0, 137.0, 38.0, 20.0 ], "text" : "set $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 10.0, "id" : "obj-21", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 127.0, 110.0, 34.0, 21.0 ], "text" : "reset" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-22", "maxclass" : "newobj", "numinlets" : 3, "numoutlets" : 3, "outlettype" : [ "int", "symbol", "" ], "patching_rect" : [ 182.0, 241.0, 183.0, 23.0 ], "text" : "attr3 @bounds 2 5 @step 1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-23", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 127.0, 91.0, 38.0, 18.0 ], "text" : "reset" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-24", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 60.0, 92.0, 43.0, 18.0 ], "text" : "trigger" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-25", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 187.0, 91.0, 59.0, 18.0 ], "text" : "set counter" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-26", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 270.0, 91.0, 57.0, 18.0 ], "text" : "set bounds" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-28", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 32.0, 16.0, 141.0, 47.0 ], "text" : "attr3" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-29", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 191.0, 29.5, 343.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-30", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 22.0, 16.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-31", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 311.0, 311.0, 100.0, 18.0 ], "text" : "attributes" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 367.5, 203.0, 191.5, 203.0 ], "source" : [ "obj-1", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 77.5, 147.0, 191.5, 147.0 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 2 ], "midpoints" : [ 410.5, 143.0, 412.0, 143.0, 412.0, 222.0, 355.5, 222.0 ], "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 2 ], "midpoints" : [ 387.5, 143.0, 412.0, 143.0, 412.0, 222.0, 355.5, 222.0 ], "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 2 ], "midpoints" : [ 368.5, 143.0, 412.0, 143.0, 412.0, 222.0, 355.5, 222.0 ], "source" : [ "obj-15", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 1 ], "midpoints" : [ 316.5, 143.0, 334.0, 143.0, 334.0, 222.0, 273.5, 222.0 ], "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 1 ], "midpoints" : [ 278.5, 143.0, 334.0, 143.0, 334.0, 222.0, 273.5, 222.0 ], "source" : [ "obj-18", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 199.5, 157.0, 191.5, 157.0 ], "source" : [ "obj-19", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 367.5, 179.0, 191.5, 179.0 ], "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 136.5, 147.0, 191.5, 147.0 ], "source" : [ "obj-21", 0 ] } } , { "patchline" : { "destination" : [ "obj-11", 0 ], "source" : [ "obj-22", 1 ] } } , { "patchline" : { "destination" : [ "obj-33", 0 ], "source" : [ "obj-22", 0 ] } } , { "patchline" : { "destination" : [ "obj-9", 0 ], "source" : [ "obj-22", 2 ] } } , { "patchline" : { "destination" : [ "obj-19", 0 ], "source" : [ "obj-27", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 273.5, 203.0, 191.5, 203.0 ], "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 273.5, 179.0, 191.5, 179.0 ], "source" : [ "obj-4", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 70.5, 236.0, 191.5, 236.0 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 70.5, 208.0, 191.5, 208.0 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 70.5, 182.0, 191.5, 182.0 ], "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "attr3.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-bind1.maxpat000066400000000000000000000314441446466241400206540ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 106.0, 112.0, 572.0, 392.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "format" : 6, "id" : "obj-7", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 144.0, 245.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-36", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 379.0, 114.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-15", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 300.0, 114.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-1", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 197.5, 35.5, 341.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 31.0, 22.0, 138.0, 47.0 ], "text" : "bind1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 48.0, 353.0, 225.0, 20.0 ], "text" : "test 232" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 48.0, 328.0, 61.0, 20.0 ], "text" : "prepend set" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 45.0, 89.0, 140.0, 18.0 ], "text" : "bind object to symbol" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 46.0, 155.0, 140.0, 18.0 ], "text" : "bind method to symbol" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 49.0, 225.0, 140.0, 18.0 ], "text" : "test message forwarding" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-11", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 379.0, 139.0, 42.0, 20.0 ], "text" : "test $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-13", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 300.0, 139.0, 42.0, 20.0 ], "text" : "test $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 379.0, 162.0, 74.0, 20.0 ], "text" : "forward sym2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-16", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 301.0, 162.0, 74.0, 20.0 ], "text" : "forward sym1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-17", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 144.0, 267.0, 49.0, 20.0 ], "text" : "sym3 $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-18", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 146.0, 191.0, 97.0, 20.0 ], "text" : "unbindmethod sym2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-19", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 45.0, 192.0, 97.0, 20.0 ], "text" : "unbindmethod sym1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-20", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 146.0, 173.0, 87.0, 20.0 ], "text" : "bindmethod sym2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-21", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 45.0, 173.0, 87.0, 20.0 ], "text" : "bindmethod sym1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-22", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 297.0, 260.0, 109.0, 20.0 ], "text" : "myforward" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-23", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 298.0, 240.0, 61.0, 20.0 ], "text" : "prepend set" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-24", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 299.0, 218.0, 42.0, 20.0 ], "text" : "r sym3" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-25", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 50.0, 241.0, 88.0, 20.0 ], "text" : "sym3 myforward" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-26", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 121.0, 127.0, 65.0, 20.0 ], "text" : "unbind sym2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-27", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 45.0, 127.0, 65.0, 20.0 ], "text" : "unbind sym1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-28", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 121.0, 108.0, 55.0, 20.0 ], "text" : "bind sym2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-29", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 45.0, 108.0, 55.0, 20.0 ], "text" : "bind sym1" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 14.0, "id" : "obj-30", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 48.0, 297.0, 46.0, 26.0 ], "text" : "bind1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-31", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 297.0, 93.0, 184.0, 18.0 ], "text" : "send message to bound object/method" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-32", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 298.0, 203.0, 140.0, 18.0 ], "text" : "receive forwarded message" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-33", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 110.5, 328.0, 168.0, 18.0 ], "text" : "message received by bound method" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-34", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 21.0, 22.0, 524.0, 49.0 ], "rounded" : 0 } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-14", 0 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-15", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 1 ], "hidden" : 1, "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "midpoints" : [ 155.5, 207.0, 36.0, 207.0, 36.0, 288.0, 52.0, 288.0, 57.5, 295.0 ], "source" : [ "obj-18", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "midpoints" : [ 54.5, 207.0, 36.0, 207.0, 36.0, 288.0, 57.5, 288.0 ], "source" : [ "obj-19", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "midpoints" : [ 155.5, 185.0, 143.0, 185.0, 143.0, 207.0, 36.0, 207.0, 36.0, 288.0, 57.5, 288.0 ], "source" : [ "obj-20", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "midpoints" : [ 54.5, 185.0, 36.0, 185.0, 36.0, 288.0, 57.5, 288.0 ], "source" : [ "obj-21", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "source" : [ "obj-23", 0 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-24", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 1 ], "hidden" : 1, "source" : [ "obj-25", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "midpoints" : [ 130.5, 147.0, 36.0, 147.0, 36.0, 288.0, 57.5, 288.0 ], "source" : [ "obj-26", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "midpoints" : [ 54.5, 147.0, 36.0, 147.0, 36.0, 288.0, 57.5, 288.0 ], "source" : [ "obj-27", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "midpoints" : [ 130.5, 125.0, 116.0, 125.0, 116.0, 147.0, 36.0, 147.0, 36.0, 288.0, 57.5, 288.0 ], "source" : [ "obj-28", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "midpoints" : [ 54.5, 125.0, 36.0, 125.0, 36.0, 288.0, 57.5, 288.0 ], "source" : [ "obj-29", 0 ] } } , { "patchline" : { "destination" : [ "obj-6", 0 ], "source" : [ "obj-30", 0 ] } } , { "patchline" : { "destination" : [ "obj-11", 0 ], "source" : [ "obj-36", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 0 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 0 ], "source" : [ "obj-7", 0 ] } } ], "dependency_cache" : [ { "name" : "bind1.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-buffer1.maxpat000066400000000000000000000316361446466241400212140ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 116.0, 171.0, 565.0, 369.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-49", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 470.0, 186.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-45", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 418.0, 186.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-43", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 366.0, 186.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-41", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 302.0, 186.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-39", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 250.0, 186.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-20", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 54.0, 297.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 161.0, 141.0, 71.0, 18.0 ], "text" : "query buffer" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 366.0, 145.0, 65.0, 18.0 ], "text" : "set sample" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 191.0, 27.5, 341.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-5", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 24.0, 14.0, 166.0, 47.0 ], "text" : "buffer1" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-6", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 13.0, 14.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 454.0, 165.0, 44.0, 18.0 ], "text" : "channel" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "newobj", "numinlets" : 3, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 368.0, 212.0, 59.0, 20.0 ], "text" : "pack 0 0. 0" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-11", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 407.0, 165.0, 44.0, 18.0 ], "text" : "value" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-12", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 367.0, 234.0, 74.0, 20.0 ], "text" : "poke $1 $2 $3" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 366.0, 165.0, 32.0, 18.0 ], "text" : "index" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-15", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 251.0, 212.0, 47.0, 20.0 ], "text" : "pack 0 0" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-16", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 291.0, 166.0, 44.0, 18.0 ], "text" : "channel" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-18", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 250.0, 234.0, 59.0, 20.0 ], "text" : "peek $1 $2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-21", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 24.0, 210.0, 61.0, 20.0 ], "text" : "getchannels" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-22", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 137.0, 178.0, 68.0, 20.0 ], "text" : "frames 1000" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-23", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 109.0, 140.0, 51.0, 20.0 ], "text" : "getbuffer" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-24", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 138.0, 196.0, 55.0, 20.0 ], "text" : "getframes" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-25", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 147.0, 317.0, 142.0, 20.0 ], "text" : "frames 1001" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-26", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 146.0, 294.0, 61.0, 20.0 ], "text" : "prepend set" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-27", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 66.0, 83.0, 22.0, 20.0 ], "text" : "set" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-28", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 143.0, 116.0, 60.0, 20.0 ], "text" : "buffer buf2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-29", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "float", "bang" ], "patching_rect" : [ 335.0, 103.0, 95.0, 20.0 ], "text" : "buffer~ buf2 100 2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-30", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 95.0, 116.0, 46.0, 20.0 ], "text" : "set buf1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-31", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "float", "bang" ], "patching_rect" : [ 336.0, 79.0, 85.0, 20.0 ], "text" : "buffer~ buf1 100" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-32", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "float", "" ], "patching_rect" : [ 91.0, 269.0, 65.0, 20.0 ], "text" : "buffer1 buf1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-33", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 54.0, 321.0, 61.0, 18.0 ], "text" : "peek value" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-34", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 250.0, 166.0, 32.0, 18.0 ], "text" : "index" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-35", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 251.0, 145.0, 65.0, 18.0 ], "text" : "get sample" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-36", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 90.0, 83.0, 100.0, 18.0 ], "text" : "set no buffer" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-37", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 95.0, 102.0, 62.0, 18.0 ], "text" : "set buffer" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-12", 0 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-18", 0 ], "source" : [ "obj-15", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-18", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-21", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-22", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-23", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-24", 0 ] } } , { "patchline" : { "destination" : [ "obj-25", 0 ], "source" : [ "obj-26", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-27", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-28", 0 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-30", 0 ] } } , { "patchline" : { "destination" : [ "obj-20", 0 ], "source" : [ "obj-32", 0 ] } } , { "patchline" : { "destination" : [ "obj-26", 0 ], "source" : [ "obj-32", 1 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "source" : [ "obj-39", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 1 ], "source" : [ "obj-41", 0 ] } } , { "patchline" : { "destination" : [ "obj-10", 0 ], "source" : [ "obj-43", 0 ] } } , { "patchline" : { "destination" : [ "obj-10", 1 ], "source" : [ "obj-45", 0 ] } } , { "patchline" : { "destination" : [ "obj-10", 2 ], "source" : [ "obj-49", 0 ] } } ], "dependency_cache" : [ { "name" : "buffer1.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-lib1.maxpat000066400000000000000000000255761446466241400205170ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 82.0, 126.0, 672.0, 340.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-47", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 20.0, 142.0, 524.0, 18.0 ], "text" : "Although this instance will not be successfully created, the library is loaded, providing access to the contained objects" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-46", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 20.0, 122.0, 524.0, 18.0 ], "presentation_linecount" : 2, "text" : "A quick (bad) hack is to instantiate an object with the library name before using other objects of the library, like here:" } } , { "box" : { "format" : 6, "id" : "obj-42", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 441.0, 209.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-43", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 379.0, 209.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-44", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 441.0, 235.0, 38.0, 20.0 ], "text" : "arg $1" } } , { "box" : { "format" : 6, "id" : "obj-39", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 286.0, 209.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-40", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 224.0, 209.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-41", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 286.0, 235.0, 38.0, 20.0 ], "text" : "arg $1" } } , { "box" : { "format" : 6, "id" : "obj-38", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 132.0, 209.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-36", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 70.0, 209.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-34", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 379.0, 287.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-32", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 224.0, 287.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-30", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 70.0, 287.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-23", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 0, "patching_rect" : [ 546.0, 120.0, 27.0, 22.0 ], "text" : "lib1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 20.0, 94.0, 630.0, 18.0 ], "text" : "This can be done by putting the library into the max-startup folder, or by creating an objectmappings file registering the contained objects." } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 437.0, 188.0, 44.0, 18.0 ], "text" : "set arg" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-8", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "float", "" ], "patching_rect" : [ 379.0, 260.0, 90.0, 23.0 ], "text" : "lib1.* @arg 2" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 376.0, 188.0, 44.0, 18.0 ], "text" : "trigger" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 286.0, 188.0, 44.0, 18.0 ], "text" : "set arg" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-15", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "float", "" ], "patching_rect" : [ 224.0, 260.0, 89.0, 23.0 ], "text" : "lib1.- @arg 7" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-16", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 224.0, 188.0, 44.0, 18.0 ], "text" : "trigger" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-17", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 132.0, 188.0, 44.0, 18.0 ], "text" : "set arg" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-18", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 132.0, 235.0, 38.0, 20.0 ], "text" : "arg $1" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-22", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "float", "" ], "patching_rect" : [ 70.0, 260.0, 100.0, 23.0 ], "text" : "lib1.+ @arg 3" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-24", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 30.0, 15.0, 147.0, 47.0 ], "text" : "lib1" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-25", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 203.0, 28.5, 336.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-26", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 20.0, 15.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-27", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 70.0, 188.0, 44.0, 18.0 ], "text" : "trigger" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-28", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 20.0, 73.0, 519.0, 18.0 ], "text" : "In MaxMSP a library of objects can be used when it is loaded before the creation of any of its objects." } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-32", 0 ], "source" : [ "obj-15", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "midpoints" : [ 141.5, 257.0, 79.5, 257.0 ], "source" : [ "obj-18", 0 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "source" : [ "obj-22", 0 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "source" : [ "obj-36", 0 ] } } , { "patchline" : { "destination" : [ "obj-18", 0 ], "source" : [ "obj-38", 0 ] } } , { "patchline" : { "destination" : [ "obj-41", 0 ], "source" : [ "obj-39", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "source" : [ "obj-40", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "midpoints" : [ 295.5, 257.0, 233.5, 257.0 ], "source" : [ "obj-41", 0 ] } } , { "patchline" : { "destination" : [ "obj-44", 0 ], "source" : [ "obj-42", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "source" : [ "obj-43", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "midpoints" : [ 450.5, 257.0, 388.5, 257.0 ], "source" : [ "obj-44", 0 ] } } , { "patchline" : { "destination" : [ "obj-34", 0 ], "source" : [ "obj-8", 0 ] } } ], "dependency_cache" : [ { "name" : "lib1.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-signal1.maxpat000066400000000000000000000136111446466241400212110ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 96.0, 125.0, 564.0, 376.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-3", "maxclass" : "ezdac~", "numinlets" : 2, "numoutlets" : 0, "patching_rect" : [ 154.0, 295.0, 45.0, 45.0 ] } } , { "box" : { "format" : 6, "id" : "obj-5", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 255.0, 172.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 211.0, 262.0, 95.0, 18.0 ], "text" : "adjust the volume" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "signal" ], "patching_rect" : [ 167.0, 259.0, 37.0, 20.0 ], "text" : "*~ 0.5" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-4", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 210.0, 91.0, 50.0, 18.0 ], "text" : "source 2" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-6", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 22.0, 15.0, 165.0, 47.0 ], "text" : "signal1" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-7", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 201.0, 28.5, 334.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-8", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 16.0, 15.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "bgcolor" : [ 1.0, 1.0, 1.0, 1.0 ], "contdata" : 1, "id" : "obj-9", "maxclass" : "multislider", "numinlets" : 1, "numoutlets" : 2, "orientation" : 0, "outlettype" : [ "", "" ], "parameter_enable" : 0, "patching_rect" : [ 255.0, 151.0, 153.0, 16.0 ], "peakcolor" : [ 0.498039215686275, 0.498039215686275, 0.498039215686275, 1.0 ], "setminmax" : [ 0.0, 1.0 ], "slidercolor" : [ 0.0, 0.0, 0.0, 1.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "signal" ], "patching_rect" : [ 205.0, 107.0, 59.0, 20.0 ], "text" : "cycle~ 880" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-11", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "signal" ], "patching_rect" : [ 140.0, 107.0, 59.0, 20.0 ], "text" : "cycle~ 440" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-13", "maxclass" : "newobj", "numinlets" : 3, "numoutlets" : 1, "outlettype" : [ "signal" ], "patching_rect" : [ 167.0, 226.0, 57.0, 23.0 ], "text" : "signal1~" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 330.0, 172.0, 95.0, 18.0 ], "text" : "control the mixing" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-15", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 145.0, 90.0, 50.0, 18.0 ], "text" : "source 1" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-13", 1 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-2", 0 ], "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-3", 1 ], "order" : 0, "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-3", 0 ], "order" : 1, "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 2 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "signal1~.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-signal2.maxpat000066400000000000000000000076231446466241400212200ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 120.0, 130.0, 577.0, 276.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-9", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 210.0, 193.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-7", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 143.0, 193.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-2", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 26.0, 15.0, 165.0, 47.0 ], "text" : "signal2" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 206.0, 28.5, 337.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-4", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 19.0, 15.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 210.0, 219.0, 60.0, 18.0 ], "text" : "vector size" } } , { "box" : { "id" : "obj-11", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 143.0, 102.0, 22.0, 22.0 ] } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-12", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 4, "outlettype" : [ "float", "int", "int", "int" ], "patching_rect" : [ 143.0, 139.0, 76.0, 23.0 ], "text" : "signal2~" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-13", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 143.0, 219.0, 60.0, 18.0 ], "text" : "sample rate" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-12", 0 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 0 ], "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-9", 0 ], "midpoints" : [ 171.5, 177.0, 219.5, 177.0 ], "source" : [ "obj-12", 1 ] } } ], "dependency_cache" : [ { "name" : "signal2~.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-simple1.maxpat000066400000000000000000000126141446466241400212270ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 99.0, 137.0, 573.0, 273.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "format" : 6, "id" : "obj-17", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 180.0, 90.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-12", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 160.0, 225.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-2", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 27.0, 15.0, 165.0, 47.0 ], "text" : "simple1" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 209.0, 28.5, 332.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-4", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 17.0, 15.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 233.0, 116.0, 280.0, 18.0 ], "text" : "int message - there's no method for int: float method is called" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-7", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 160.0, 90.0, 17.0, 20.0 ], "text" : "1." } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 204.0, 145.0, 17.0, 20.0 ], "text" : "0." } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 205.0, 119.0, 16.0, 20.0 ], "text" : "2" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-11", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "patching_rect" : [ 160.0, 194.0, 66.0, 23.0 ], "text" : "simple1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-13", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 239.0, 92.0, 100.0, 18.0 ], "text" : "float messages" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 231.0, 146.0, 60.0, 18.0 ], "text" : "special case" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-15", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 215.0, 227.0, 47.0, 18.0 ], "text" : "inverse" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-11", 0 ], "midpoints" : [ 214.5, 142.0, 169.5, 142.0 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-12", 0 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-11", 0 ], "midpoints" : [ 189.5, 128.5, 169.5, 128.5 ], "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-11", 0 ], "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-11", 0 ], "midpoints" : [ 213.5, 179.0, 169.5, 179.0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "simple1.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-simple2.maxpat000066400000000000000000000102341446466241400212240ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 107.0, 146.0, 578.0, 276.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "format" : 6, "id" : "obj-16", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 145.0, 196.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-14", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 213.0, 130.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-7", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 145.0, 130.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 27.0, 15.0, 165.0, 47.0 ], "text" : "simple2" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-4", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 206.0, 28.5, 333.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-5", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 19.0, 15.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 138.0, 106.0, 56.0, 18.0 ], "text" : "triggering" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-9", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "float" ], "patching_rect" : [ 145.0, 165.0, 71.0, 23.0 ], "text" : "simple2 3" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-11", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 213.0, 107.0, 70.0, 18.0 ], "text" : "not triggering" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-12", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 223.0, 169.0, 102.0, 18.0 ], "text" : "3 is default argument" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-9", 1 ], "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-9", 0 ], "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "simple2.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-simple3.maxpat000066400000000000000000000151601446466241400212300ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 112.0, 129.0, 581.0, 297.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 348.0, 220.0, 107.0, 18.0 ], "presentation_linecount" : 2, "text" : "other tag (unhandled)" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-16", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 283.0, 218.0, 32.0, 20.0 ], "text" : "other" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-2", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 29.0, 16.0, 165.0, 47.0 ], "text" : "simple3" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 204.5, 29.5, 339.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-4", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 19.0, 16.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 348.0, 192.0, 88.0, 18.0 ], "text" : "symbol message" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 283.0, 192.0, 63.0, 20.0 ], "text" : "symbol yeah" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-7", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 324.0, 166.0, 100.0, 18.0 ], "text" : "tag and argument" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 283.0, 164.0, 35.0, 20.0 ], "text" : "hula 1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 268.0, 133.0, 26.0, 20.0 ], "text" : "hula" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-10", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 245.0, 133.0, 18.0, 20.0 ], "text" : "to" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-11", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 214.0, 133.0, 28.0, 20.0 ], "text" : "born" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 10.0, "id" : "obj-12", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 140.0, 92.0, 28.0, 21.0 ], "text" : "help" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-13", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 214.0, 253.0, 65.0, 23.0 ], "text" : "simple3" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-14", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 171.0, 95.0, 100.0, 18.0 ], "text" : "issue help message" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-15", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 305.0, 134.0, 104.0, 18.0 ], "text" : "tag without argument" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-13", 0 ], "midpoints" : [ 254.5, 177.0, 223.5, 177.0 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "midpoints" : [ 149.5, 176.0, 223.5, 176.0 ], "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "midpoints" : [ 292.5, 244.0, 223.5, 244.0 ], "source" : [ "obj-16", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "midpoints" : [ 292.5, 214.5, 223.5, 214.5 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "midpoints" : [ 292.5, 189.5, 223.5, 189.5 ], "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "midpoints" : [ 277.5, 177.0, 223.5, 177.0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "simple3.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-thread1.maxpat000066400000000000000000000220061446466241400212010ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 186.0, 190.0, 580.0, 297.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-26", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 125.0, 108.0, 289.0, 18.0 ], "text" : "the thread will count to 19 and then stop" } } , { "box" : { "id" : "obj-25", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 382.0, 238.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-23", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 310.0, 238.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-15", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 237.0, 238.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-10", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 165.0, 238.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-4", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 92.0, 238.0, 50.0, 22.0 ] } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-2", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "int" ], "patching_rect" : [ 382.0, 208.0, 56.0, 23.0 ], "text" : "thread1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-3", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "bang" ], "patching_rect" : [ 382.0, 169.0, 54.0, 20.0 ], "text" : "delay 200" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-5", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "int" ], "patching_rect" : [ 310.0, 208.0, 56.0, 23.0 ], "text" : "thread1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "bang" ], "patching_rect" : [ 310.0, 169.0, 54.0, 20.0 ], "text" : "delay 200" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-8", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "int" ], "patching_rect" : [ 237.0, 208.0, 56.0, 23.0 ], "text" : "thread1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "bang" ], "patching_rect" : [ 237.0, 169.0, 54.0, 20.0 ], "text" : "delay 200" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-12", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "int" ], "patching_rect" : [ 165.0, 208.0, 56.0, 23.0 ], "text" : "thread1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-13", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "bang" ], "patching_rect" : [ 165.0, 169.0, 54.0, 20.0 ], "text" : "delay 200" } } , { "box" : { "id" : "obj-14", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 92.0, 96.0, 30.0, 30.0 ] } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-16", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 29.0, 16.0, 165.0, 47.0 ], "text" : "thread1" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-17", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 205.0, 29.5, 332.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-18", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 19.0, 16.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-19", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 125.0, 89.0, 69.0, 18.0 ], "text" : "click to start" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-20", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 125.0, 128.0, 289.0, 18.0 ], "text" : "(if you click twice, the same thread is started a second time)" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-21", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "int" ], "patching_rect" : [ 92.0, 209.0, 56.0, 23.0 ], "text" : "thread1" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-10", 0 ], "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-12", 0 ], "order" : 1, "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-9", 0 ], "midpoints" : [ 174.5, 191.0, 228.0, 191.0, 228.0, 162.0, 246.5, 162.0 ], "order" : 0, "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "order" : 0, "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-21", 0 ], "order" : 1, "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-25", 0 ], "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-4", 0 ], "source" : [ "obj-21", 0 ] } } , { "patchline" : { "destination" : [ "obj-2", 0 ], "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-3", 0 ], "midpoints" : [ 319.5, 192.0, 372.0, 192.0, 372.0, 162.0, 391.5, 162.0 ], "order" : 0, "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 0 ], "order" : 1, "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-6", 0 ], "midpoints" : [ 246.5, 192.0, 301.0, 192.0, 301.0, 162.0, 319.5, 162.0 ], "order" : 0, "source" : [ "obj-9", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "order" : 1, "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "thread1.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-thread2.maxpat000066400000000000000000000222651446466241400212110ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 57.0, 118.0, 569.0, 290.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-18", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 368.0, 242.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-15", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 229.0, 242.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-14", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 104.0, 242.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 417.0, 181.0, 27.0, 20.0 ], "text" : "text" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 383.0, 181.0, 28.0, 20.0 ], "text" : "stop" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-3", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 363.0, 181.0, 16.0, 20.0 ], "text" : "0" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-4", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 278.0, 181.0, 27.0, 20.0 ], "text" : "text" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 244.0, 181.0, 28.0, 20.0 ], "text" : "stop" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-6", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 224.0, 181.0, 16.0, 20.0 ], "text" : "0" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-7", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 152.0, 181.0, 27.0, 20.0 ], "text" : "text" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 118.0, 181.0, 28.0, 20.0 ], "text" : "stop" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 98.0, 181.0, 16.0, 20.0 ], "text" : "0" } } , { "box" : { "id" : "obj-10", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 290.0, 109.0, 30.0, 30.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-11", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 292.0, 95.0, 30.0, 18.0 ], "text" : "stop" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-13", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 368.0, 213.0, 76.0, 23.0 ], "text" : "thread2 50" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-16", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 229.0, 213.0, 76.0, 23.0 ], "text" : "thread2 15" } } , { "box" : { "id" : "obj-17", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 217.0, 110.0, 30.0, 30.0 ] } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-19", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 29.0, 16.0, 165.0, 47.0 ], "text" : "thread2" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-20", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 204.0, 29.5, 332.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-21", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 19.0, 16.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-22", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 219.0, 96.0, 30.0, 18.0 ], "text" : "start" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-23", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 104.0, 213.0, 69.0, 23.0 ], "text" : "thread2 3" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-1", 0 ] } } , { "patchline" : { "destination" : [ "obj-2", 0 ], "order" : 0, "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 0 ], "order" : 1, "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "order" : 2, "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-18", 0 ], "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "source" : [ "obj-16", 0 ] } } , { "patchline" : { "destination" : [ "obj-3", 0 ], "order" : 0, "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-6", 0 ], "order" : 1, "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-9", 0 ], "order" : 2, "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-14", 0 ], "source" : [ "obj-23", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "source" : [ "obj-4", 0 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ ], "autosave" : 0 } } flext-0-6-3/tutorial/maxmsp/ex-timer1.maxpat000066400000000000000000000333731446466241400210630ustar00rootroot00000000000000{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 3, "revision" : 1, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 99.0, 159.0, 591.0, 336.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-37", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 134.5, 285.0, 24.0, 24.0 ] } } , { "box" : { "fontsize" : 9.0, "id" : "obj-35", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 200.5, 266.0, 56.0, 19.0 ], "text" : "prepend set" } } , { "box" : { "id" : "obj-34", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 200.5, 289.0, 192.0, 22.0 ], "text" : "\"Timer A\"" } } , { "box" : { "format" : 6, "id" : "obj-24", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 438.0, 114.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-19", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 367.0, 115.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-15", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 294.0, 115.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-11", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 224.0, 116.0, 50.0, 22.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-1", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 41.0, 184.0, 53.0, 20.0 ], "text" : "getostime" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-2", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 41.0, 159.0, 43.0, 20.0 ], "text" : "gettime" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 361.0, 99.0, 121.0, 18.0 ], "text" : "trigger a periodic event" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-4", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 224.0, 99.0, 112.0, 18.0 ], "text" : "trigger a single event" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-5", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "float" ], "patching_rect" : [ 422.5, 140.0, 33.0, 20.0 ], "text" : "f 600" } } , { "box" : { "id" : "obj-6", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 423.0, 114.0, 15.0, 15.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-8", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 423.0, 165.0, 65.0, 20.0 ], "text" : "periodicB $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-9", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "float" ], "patching_rect" : [ 351.5, 141.0, 33.0, 20.0 ], "text" : "f 500" } } , { "box" : { "id" : "obj-10", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 352.0, 115.0, 15.0, 15.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-12", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 352.0, 166.0, 65.0, 20.0 ], "text" : "periodicA $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-13", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "float" ], "patching_rect" : [ 279.5, 141.0, 39.0, 20.0 ], "text" : "f 2000" } } , { "box" : { "id" : "obj-14", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 280.0, 115.0, 15.0, 15.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-16", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 280.0, 165.0, 64.0, 20.0 ], "text" : "oneshotB $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-17", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "float" ], "patching_rect" : [ 208.5, 142.0, 39.0, 20.0 ], "text" : "f 1000" } } , { "box" : { "id" : "obj-18", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 209.0, 116.0, 15.0, 15.0 ] } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-20", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 209.0, 166.0, 65.0, 20.0 ], "text" : "oneshotA $1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-21", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 151.0, 116.0, 39.0, 20.0 ], "text" : "resetB" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-22", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 108.0, 116.0, 40.0, 20.0 ], "text" : "resetA" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-23", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 160.0, 289.0, 31.0, 20.0 ], "text" : "print" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 36.0, "id" : "obj-25", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 25.0, 15.0, 165.0, 47.0 ], "text" : "timer1" } } , { "box" : { "fontname" : "Courier New", "fontsize" : 14.0, "id" : "obj-26", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 200.5, 28.5, 332.0, 22.0 ], "text" : "flext tutorial, (C)2002-2022 grrrr.org" } } , { "box" : { "bgcolor" : [ 0.87843137254902, 0.6, 0.352941176470588, 1.0 ], "bordercolor" : [ 0.0, 0.0, 0.0, 1.0 ], "id" : "obj-27", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 17.0, 15.0, 524.0, 49.0 ], "rounded" : 0 } } , { "box" : { "fontname" : "Geneva", "fontsize" : 10.0, "id" : "obj-28", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 40.0, 116.0, 33.0, 21.0 ], "text" : "help" } } , { "box" : { "color" : [ 1.0, 0.36078431372549, 0.682352941176471, 1.0 ], "fontname" : "Geneva", "fontsize" : 12.0, "id" : "obj-29", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 160.0, 231.0, 50.0, 23.0 ], "text" : "timer1" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-30", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 115.0, 98.0, 63.0, 18.0 ], "text" : "reset timer" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-31", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 86.0, 159.0, 100.0, 18.0 ], "text" : "get system time" } } , { "box" : { "fontname" : "Geneva", "fontsize" : 9.0, "id" : "obj-32", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 99.0, 183.0, 61.0, 18.0 ], "text" : "get OS time" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 50.5, 217.0, 169.5, 217.0 ], "source" : [ "obj-1", 0 ] } } , { "patchline" : { "destination" : [ "obj-9", 0 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 1 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 361.5, 204.5, 169.5, 204.5 ], "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 1 ], "source" : [ "obj-15", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 289.5, 204.0, 169.5, 204.0 ], "source" : [ "obj-16", 0 ] } } , { "patchline" : { "destination" : [ "obj-20", 0 ], "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 0 ], "source" : [ "obj-18", 0 ] } } , { "patchline" : { "destination" : [ "obj-9", 1 ], "source" : [ "obj-19", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 50.5, 217.5, 169.5, 217.5 ], "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 218.5, 204.5, 169.5, 204.5 ], "source" : [ "obj-20", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 160.5, 150.5, 169.5, 150.5 ], "source" : [ "obj-21", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 117.5, 148.5, 169.5, 148.5 ], "source" : [ "obj-22", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 1 ], "source" : [ "obj-24", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 49.5, 148.0, 169.5, 148.0 ], "source" : [ "obj-28", 0 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "order" : 1, "source" : [ "obj-29", 1 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "order" : 1, "source" : [ "obj-29", 0 ] } } , { "patchline" : { "destination" : [ "obj-35", 0 ], "order" : 0, "source" : [ "obj-29", 1 ] } } , { "patchline" : { "destination" : [ "obj-35", 0 ], "order" : 0, "source" : [ "obj-29", 0 ] } } , { "patchline" : { "destination" : [ "obj-37", 0 ], "order" : 2, "source" : [ "obj-29", 0 ] } } , { "patchline" : { "destination" : [ "obj-34", 0 ], "source" : [ "obj-35", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 0 ], "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "midpoints" : [ 432.5, 204.0, 169.5, 204.0 ], "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-12", 0 ], "source" : [ "obj-9", 0 ] } } ], "dependency_cache" : [ { "name" : "timer1.mxo", "type" : "iLaX" } ], "autosave" : 0 } } flext-0-6-3/tutorial/pd/000077500000000000000000000000001446466241400151215ustar00rootroot00000000000000flext-0-6-3/tutorial/pd/Makefile.am000066400000000000000000000000001446466241400171430ustar00rootroot00000000000000flext-0-6-3/tutorial/pd/ex-adv1.pd000066400000000000000000000012151446466241400167120ustar00rootroot00000000000000#N canvas 46 58 592 347 12; #X msg 34 92 or two words; #X msg 169 93 2 3; #X obj 72 213 print result; #X obj 16 8 cnv 15 550 40 empty empty adv1 10 22 0 24 #fcac44 #000000 0; #X text 173 214 watch the console!; #X text 134 117 send the object various messages; #X obj 66 127 nbx 3 18 0 100 0 0 empty empty empty 0 -6 0 14 #fcfcfc #000000 #000000 0 256; #X obj 49 172 adv1 one; #X obj 48 260 prepend set; #X text 140 260 prepend is defined as an alias of adv1; #X text 146 20 flext tutorial \, (C)2002-2022 grrrr.org; #X msg 48 299; #X connect 0 0 7 0; #X connect 1 0 7 0; #X connect 6 0 7 0; #X connect 7 0 2 0; #X connect 7 0 8 0; #X connect 8 0 11 0; flext-0-6-3/tutorial/pd/ex-adv2.pd000066400000000000000000000013211446466241400167110ustar00rootroot00000000000000#N canvas 329 97 595 356 12; #X msg 26 97 help; #X msg 123 146 born; #X msg 172 147 to; #X msg 214 149 hula; #X msg 228 192 hula 1; #X text 261 150 tag without argument; #X text 297 190 tag and argument; #X text 72 97 print a help message; #X obj 16 7 cnv 15 550 40 empty empty adv2 10 22 0 24 #fcac44 #000000 0; #X text 21 49 this is identical to the simple3 example; #X text 345 223 symbol message; #X msg 228 222 symbol yeah; #X obj 123 294 adv2; #X text 150 18 flext tutorial \, (C)2002-2022 grrrr.org; #X msg 228 253 other; #X text 283 254 other message (unhandled); #X connect 0 0 12 0; #X connect 1 0 12 0; #X connect 2 0 12 0; #X connect 3 0 12 0; #X connect 4 0 12 0; #X connect 11 0 12 0; #X connect 14 0 12 0; flext-0-6-3/tutorial/pd/ex-adv3.pd000066400000000000000000000022201446466241400167110ustar00rootroot00000000000000#N canvas 82 94 603 359 12; #X obj 16 7 cnv 15 550 40 empty empty adv3 10 22 0 24 #fcac44 #000000 0; #X obj 305 303 bng 15 250 50 0 empty empty empty 0 -6 0 8 #fcfcfc #000000 #000000; #X obj 223 300 nbx 5 18 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X msg 269 130 1 10; #X msg 389 128 1; #X msg 429 128 -1; #X msg 469 128 2; #X obj 88 129 bng 25 250 50 0 empty empty empty 0 -6 0 8 #fc2828 #000000 #000000; #X msg 317 130 7 2; #X text 325 300 end has been reached; #X obj 157 127 nbx 5 18 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X msg 158 150 set \$1; #X text 72 108 trigger; #X text 147 108 set counter; #X text 264 109 set bounds; #X text 390 106 set step size; #X msg 80 196 reset; #X text 83 176 reset; #X text 21 49 this is a port of IOhannes Zmoelnigs "counter" example ; #X obj 229 266 adv3 2 5 1; #X text 182 18 flext tutorial \, (C)2002-2022 grrrr.org; #X connect 3 0 19 1; #X connect 4 0 19 2; #X connect 5 0 19 2; #X connect 6 0 19 2; #X connect 7 0 19 0; #X connect 8 0 19 1; #X connect 10 0 11 0; #X connect 11 0 19 0; #X connect 16 0 19 0; #X connect 19 0 2 0; #X connect 19 1 1 0; flext-0-6-3/tutorial/pd/ex-attr1.pd000066400000000000000000000021151446466241400171120ustar00rootroot00000000000000#N canvas 95 81 591 424 12; #X text 114 273 attribute as a creation arg; #X msg 160 98 getattributes; #X text 167 319 there is one additional outlet; #X text 167 334 for all attribute-enabled objects; #X obj 150 367 print; #X msg 160 141 getarg; #X text 12 92 trigger output; #X msg 160 203 arg \$1; #X text 230 191 set attribute "arg"; #X text 295 98 query object attributes (watch console); #X text 228 142 query attribute "arg" (watch console); #X obj 16 8 cnv 15 550 40 empty empty attr1 10 22 0 24 #fcac44 #000000 0; #X text 26 388 result; #X obj 23 114 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 29 370 nbx 7 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 161 181 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X text 175 18 flext tutorial \, (C)2002-2022 grrrr.org; #X obj 59 296 attr1 @arg 3; #X text 197 370 watch console!; #X connect 1 0 17 0; #X connect 5 0 17 0; #X connect 7 0 17 0; #X connect 13 0 17 0; #X connect 15 0 7 0; #X connect 17 0 14 0; #X connect 17 1 4 0; flext-0-6-3/tutorial/pd/ex-attr2.pd000066400000000000000000000025411446466241400171160ustar00rootroot00000000000000#N canvas 45 62 580 407 12; #X msg 22 88 getattributes; #X text 264 326 there is one additional outlet; #X text 264 341 for all attribute-enabled objects; #X obj 246 365 print; #X msg 22 124 getarg; #X text 14 218 trigger output; #X msg 270 263 arg \$1; #X text 159 87 query object attributes (watch console); #X msg 95 124 getop; #X text 251 124 query attributes; #X text 332 179 set attributes; #X msg 168 169 op +; #X msg 167 194 op -; #X msg 218 169 op *; #X msg 268 193 op **; #X msg 268 169 op =; #X msg 218 193 op /; #X msg 157 124 getresult; #X obj 16 8 cnv 15 550 40 empty empty attr2 10 22 0 24 #fcac44 #000000 0; #X text 90 367 result; #X obj 22 240 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 270 242 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 150 367 nbx 7 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X text 327 243 set argument; #X obj 158 306 attr2 @op +; #X text 171 19 flext tutorial \, (C)2002-2022 grrrr.org; #X connect 0 0 24 0; #X connect 4 0 24 0; #X connect 6 0 24 0; #X connect 8 0 24 0; #X connect 11 0 24 0; #X connect 12 0 24 0; #X connect 13 0 24 0; #X connect 14 0 24 0; #X connect 15 0 24 0; #X connect 16 0 24 0; #X connect 17 0 24 0; #X connect 20 0 24 0; #X connect 21 0 6 0; #X connect 24 0 22 0; #X connect 24 1 3 0; flext-0-6-3/tutorial/pd/ex-attr3.pd000066400000000000000000000032061446466241400171160ustar00rootroot00000000000000#N canvas 84 73 579 420 12; #X obj 16 7 cnv 15 550 40 empty empty attr3 10 22 0 24 #fcac44 #000000 0; #X obj 293 364 bng 15 250 50 0 empty empty empty 0 -6 0 8 #fcfcfc #000000 #000000; #X obj 196 361 nbx 5 18 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X msg 296 126 1 10; #X msg 419 127 1; #X msg 459 127 -1; #X msg 498 127 2; #X obj 36 128 bng 25 250 50 0 empty empty empty 0 -6 0 8 #fc2828 #000000 #000000; #X msg 344 126 7 2; #X obj 173 119 nbx 5 18 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X msg 174 142 set \$1; #X text 20 107 trigger; #X text 163 100 set counter; #X text 291 105 set bounds; #X text 420 105 set step size; #X msg 97 135 reset; #X text 100 115 reset; #X text 21 64 with attributes; #X msg 32 195 getattributes; #X obj 392 363 print; #X text 385 381 attributes; #X msg 32 237 getcount; #X msg 388 232 getstep; #X text 22 178 list all attributes; #X msg 32 266 count 3; #X text 117 238 get count; #X text 112 266 set count; #X msg 387 259 step 3; #X text 21 49 this is a port of IOhannes Zmoelnigs "counter" example ; #X msg 258 234 getbounds; #X msg 257 261 bounds 5 15; #X obj 197 327 attr3 @bounds 2 5 @step 1; #X text 174 17 flext tutorial \, (C)2002-2022 grrrr.org; #X connect 3 0 31 1; #X connect 4 0 31 2; #X connect 5 0 31 2; #X connect 6 0 31 2; #X connect 7 0 31 0; #X connect 8 0 31 1; #X connect 9 0 10 0; #X connect 10 0 31 0; #X connect 15 0 31 0; #X connect 18 0 31 0; #X connect 21 0 31 0; #X connect 22 0 31 0; #X connect 24 0 31 0; #X connect 27 0 31 0; #X connect 29 0 31 0; #X connect 30 0 31 0; #X connect 31 0 2 0; #X connect 31 1 1 0; #X connect 31 2 19 0; flext-0-6-3/tutorial/pd/ex-bind1.pd000066400000000000000000000030451446466241400170570ustar00rootroot00000000000000#N canvas 87 93 585 403 12; #X obj 15 8 cnv 15 550 40 empty empty bind1 10 22 0 24 #fcac44 #000000 0; #X text 32 72 bind object to symbol; #X msg 34 94 bind sym1; #X msg 158 94 bind sym2; #X msg 32 126 unbind sym1; #X msg 157 125 unbind sym2; #X text 27 159 bind object to symbol; #X msg 29 181 bindmethod sym1; #X msg 31 213 unbindmethod sym1; #X msg 230 181 bindmethod sym2; #X msg 233 212 unbindmethod sym2; #X obj 25 357 print OUT; #X text 121 356 watch the console!; #X obj 354 103 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 #fcfcc8 #000000 #000000 0 256; #X obj 449 103 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 #fcfcc8 #000000 #000000 0 256; #X msg 354 122 test \$1; #X msg 449 122 test \$1; #X obj 354 155 s sym1; #X obj 449 155 s sym2; #X text 352 67 send message to bound; #X text 353 81 object or method; #X obj 348 272 r sym3; #X text 347 250 receive forwarded message; #X obj 348 298 print MSG; #X text 59 250 receive forwarded message; #X msg 60 271 sym3 myforward; #X obj 205 280 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 #fcfcc8 #000000 #000000 0 256; #X msg 204 297 sym3 \$1; #X text 186 19 flext tutorial \, (C)2002-2022 grrrr.org; #X obj 26 328 bind1; #X connect 2 0 29 0; #X connect 3 0 29 0; #X connect 4 0 29 0; #X connect 5 0 29 0; #X connect 7 0 29 0; #X connect 8 0 29 0; #X connect 9 0 29 0; #X connect 10 0 29 0; #X connect 13 0 15 0; #X connect 14 0 16 0; #X connect 15 0 17 0; #X connect 16 0 18 0; #X connect 21 0 23 0; #X connect 25 0 29 1; #X connect 26 0 27 0; #X connect 27 0 29 1; #X connect 29 0 11 0; flext-0-6-3/tutorial/pd/ex-buffer1.pd000066400000000000000000000172471446466241400174250ustar00rootroot00000000000000#N canvas 66 77 762 494 12; #X obj 11 18 cnv 15 550 40 empty empty buffer1 10 22 0 24 #fcac44 #000000 0; #N canvas 0 22 450 300 (subpatch) 0; #X array buf1 1000 float 1; #A 0 -2.38419e-07 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0142856 0.0171427 0.0199999 0.022857 0.0257142 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0299999 0.0314285 0.0328571 0.0342857 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.0428572 0.464567 0.464567 0.0428572 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.0428572 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 -0 0.464567 0.464567 0.464567 -0 -0 0.464567 -0 -0 0.464567 0.464567 0.464567 0.464567 -0 0.464567 0.464567 0.464567 0.464567 -0 0.464567 -0 0.464567 -0 0.464567 0.464567 -0 0.464567 -0 -0 0.464567 -0 -0 -0 -0 -0 0.464567 -0 -0 -0 0.464567 -0 -0 0.464567 -0 -0 -0 -0 0.464567 -0 -0 0.464567 -0 -0 -0 0.464567 -0 0.464567 0.51 0.51 0.464567 0 0.464567 0 0 0.464567 0 0 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0 0.464567 0 0.464567 0 0.464567 0 0.464567 0 0 0.464567 0 0 0.464567 -0 -0 0.51 0.51 0.464567 0.00285711 0.00571423 0.464567 0.0114285 0.0142856 0.464567 0.0190474 0.464567 0.0238093 0.0261902 0.464567 0.030952 0.464567 0.0357139 0.464567 0.464567 0.464567 0.0452376 0.0476185 0.0499995 0.0523804 0.464567 0.0571422 0.0595232 0.0619041 0.064285 0.0666659 0.0690469 0.51 0.0738087 0.464567 0.0785706 0.0809515 0.0833325 0.0857134 0.0857134 0.0857134 0.0857134 0.464567 0.0857134 0.51 0.0799992 0.51 0.0742849 0.464567 0 0 0 0 0.464567 0 0 0 0.464567 0 0 0 0 0.464567 0.51 0 0 0.464567 0 0 0.51 0 0 0 0.464567 0 0.51 0 0.51 0.464567 0 0.51 0.464567 0 0.464567 0 0.51 0.464567 0.51 0.51 0.464567 0.51 0.51 0.464567 0 0 0 0.464567 0.51 0 0.464567 0 0 0 0.464567 0 0 0.464567 0 0 0.464567 0 0 0.464567 0.464567 0 0.464567 0.464567 0.464567 0 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0.464567 0 0 0 0 0.464567 0 0 0 0 0 0 0.51 0 0 0 0 0.464567 0 0 0 0 0 0.51 0 0 0 0 0 0.464567 0 0 0.51 0.51 0 0 0.51 0 0 0 0.464567 0 0 0 0 0 0 0 0 0 0.464567 0 0 0 0 0 0.464567 0 0 0 0 0 0 0 0.464567 0 0 0.464567 0 0 0.464567 0 0.464567 0 0.464567 0 0 0.464567 0 0.464567 0 0.464567 0.464567 0 0 0.464567 0 0.464567 0 0 0.464567 -0 -0.685039 -0.685039 -0.685039 -0.685039 0.0171427 0.0199998 -0.685039 -0.685039 0.0285711 -0.685039 0.0342854 -0.685039 0.0399996 0.464567 0.0457138 -0.685039 0.464567 0.464567 0.464567 0.464567 0.0628565 -0.685039 0.464567 0.0714278 0.0728564 0.464567 -0.685039 0.077142 0.0785706 0.0799991 0.464567 0.0828563 -0.685039 0.0857134 0.464567 0.0857134 0.0857134 -0.685039 0.0857134 -0.685039 0.0857134 0.0857134 0.0857134 -0.685039 -0.685039 0.0857134 0.0857134 0.0857134 0.0857134 0.0828563 0.0799992 0.077142 0.0742849 0.0714278 0.0714278 -0.685039 0.0714278 0.464567 0.0714278 0.0714278 0.0714278 0.0714278 0.0714278 0.0714278 -0.685039 0.0657136 0.0628565 0.0599994 -0.685039 0 0 0 0 0.464567 0 0 -0.685039 0 0 0 0 -0.685039 0 0 0 0 0 0 0.464567 0 -0.685039 -0.685039 0 0 0 0 0 0 0 0 0 0 0 0.464567 0 0 0 -0.685039 -0.685039 0 0 0 0 0 0 0 0 0 -0.685039 0.464567 0 0 0 0 0 0 0 -0.685039 0 0 -0.685039 0 0.464567 0 0 -0.685039 0 0 0 0 0 0 -0.685039 0 0 0 0 0.464567 0 0 -0.685039 0 -0.685039 0 0 0 0.464567 0 -0.685039 0 0 -0.685039 0 0.464567 0 0 0.464567 0 -0.685039 -0.685039 0 0.464567 -0.685039 -0.685039 0 -0.685039 0 -0.685039 0 0 -0.685039 0.464567 -0.685039 -0.685039 0.464567 0 0.464567 0.464567 -0.685039 -0.685039 0.464567 0 0.464567 -0.685039 0.464567 -0.685039 0.464567 -0.685039 0 0.464567 -0.685039 0 0.464567 -0.685039 -0.685039 0.464567 -0.685039 0 -0.685039 -0.685039 -0.685039 -0.685039 0.464567 0.464567 -0.685039 0.464567 -0.685039 0.464567 0.464567 0 0 0.464567 -0.685039 -0.685039 0 0 0.464567 -0.685039 0.464567 0 0 0 -0.685039 0.464567 0.464567 0 0 -0.685039 -0.685039 0.464567 0 0 0.464567 0.464567 -0.685039 0.464567 -0.685039 -0.685039 0 -0.685039 0.464567 0.464567 0.464567 -0.685039 -0.685039 0.464567 0.464567 -0.685039 -0.685039 -0.685039 -0.685039 0.464567 0 0.464567 -0.685039 -0.685039 0.464567 0 0 0 -0.685039 -0.685039 -0.685039 0.464567 -0.685039 0.464567 0.464567 0 0.464567 -0.685039 -0.685039 -0.685039 -0.685039 0.464567 0 -0.685039 0 0 0 0 0 -0.685039 -0.685039 0 -0.685039 0 0 -0.685039 0 -0.685039 0 -0.685039 -0.685039 0 0 0 -0.685039 -0.685039 0 0 -0.685039 0 -0.685039 0 -0.685039 -0.685039 0 -0.685039 0 -0.685039 0 0 -0.685039 -0.685039 0 -0.685039 0 -0.685039 -0.685039 0 0 0 -0.685039 -0.685039 0 0 0 -0.685039 -0.685039 0 -0.685039 0 0 -0.685039 0 0 -0.685039 -0.685039 0 0 0 -0.685039 0 -0.685039 -0.685039 0 -0.685039 -0.685039 0 0 -0.685039 -0.685039 -0.685039 -0.685039 -0.685039 0 -0.685039 -0.685039 -0.685039 -0.685039 0 -0.685039 -0.685039 -0.685039 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X coords 0 1 999 -1 200 140 1; #X restore 537 76 graph; #N canvas 0 22 450 300 (subpatch) 0; #X array buf2 300 float 1; #A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X coords 0 1 299 -1 200 140 1; #X restore 537 234 graph; #X obj 24 436 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 #fcfcc8 #000000 #000000 0 256; #X text 19 453 peek value; #X obj 137 430 print A; #X text 137 451 print attributes to the console; #X msg 41 76 set; #X msg 65 128 set buf1; #X msg 154 128 buffer buf2; #X msg 65 159 getbuffer; #X text 164 159 query current buffer; #X text 73 73 set no buffer; #X text 68 108 set buffer; #X msg 84 215 frames 1000; #X msg 85 243 getframes; #X text 199 215 set buffer length; #X text 184 243 query buffer length; #X msg 16 295 getchannels; #X text 23 320 always 1 for PD!; #X obj 231 311 nbx 5 14 0 1e+37 0 0 empty empty index 0 -6 0 10 #fcfcc8 #000000 #000000 0 256; #X obj 336 311 nbx 5 14 0 1e+37 0 0 empty empty index 0 -6 0 10 #feffc6 #000000 #000000 0 256; #X obj 334 334 pack 0 0; #X msg 335 361 poke \$1 \$2 0; #X msg 230 361 peek \$1 0; #X text 230 283 get sample; #X text 335 281 set sample; #X text 179 27 flext tutorial \, (C)2002-2022 grrrr.org; #X obj 24 398 buffer1; #X obj 396 310 hsl 128 15 -1 1 0 0 empty empty value -2 -8 0 10 #feffc6 #000000 #000000 0 1; #X connect 7 0 28 0; #X connect 8 0 28 0; #X connect 9 0 28 0; #X connect 10 0 28 0; #X connect 14 0 28 0; #X connect 15 0 28 0; #X connect 18 0 28 0; #X connect 20 0 24 0; #X connect 21 0 22 0; #X connect 22 0 23 0; #X connect 23 0 28 0; #X connect 24 0 28 0; #X connect 28 0 3 0; #X connect 28 1 5 0; #X connect 29 0 22 1; flext-0-6-3/tutorial/pd/ex-lib1.pd000066400000000000000000000035751446466241400167210ustar00rootroot00000000000000#N canvas 89 99 585 322 12; #X declare -lib lib1; #X msg 100 203 arg \$1; #X text 99 155 set arg; #X msg 283 202 arg \$1; #X text 282 156 set arg; #X msg 470 205 arg \$1; #X text 469 159 set arg; #X text 23 154 trigger; #X text 205 158 trigger; #X text 389 159 trigger; #X obj 16 8 cnv 15 550 40 empty empty lib1 10 22 0 24 #fcac44 #000000 0; #X obj 28 178 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 99 177 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 210 178 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 282 180 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 392 180 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 470 183 nbx 4 16 -999 999 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 28 272 nbx 7 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 208 272 nbx 7 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 390 272 nbx 7 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X text 25 56 In order to use the objects the library must have been ; #X text 185 17 flext tutorial \, (C)2002-2022 grrrr.org; #X obj 406 113 declare -lib lib1; #X obj 28 239 lib1.+ @arg 3; #X obj 208 241 lib1.- @arg 7; #X obj 390 243 lib1.* @arg 2; #X text 25 114 Or use the declare object (with paths set) like here: ; #X text 24 73 loaded at Pd startup (with the "-lib lib1" argument \, or in the startup objects list of the preferences); #X connect 0 0 22 0; #X connect 2 0 23 0; #X connect 4 0 24 0; #X connect 10 0 22 0; #X connect 11 0 0 0; #X connect 12 0 23 0; #X connect 13 0 2 0; #X connect 14 0 24 0; #X connect 15 0 4 0; #X connect 22 0 16 0; #X connect 23 0 17 0; #X connect 24 0 18 0; flext-0-6-3/tutorial/pd/ex-signal1.pd000066400000000000000000000015651446466241400174250ustar00rootroot00000000000000#N canvas 120 103 586 291 12; #X obj 250 121 hsl 128 15 0 1 0 0 empty empty empty 20 8 0 8 #fce0c0 #000000 #000000 0 1; #X obj 28 121 osc~ 440; #X obj 87 248 dac~; #X obj 123 121 osc~ 880; #X obj 16 8 cnv 15 550 40 empty empty signal1 10 22 0 24 #fcac44 #000000 0; #X text 342 138 control the mixing; #X text 166 210 adjust the volume; #X text 25 102 source 1; #X text 125 101 source 2; #X obj 248 143 nbx 5 16 0 1 0 0 empty empty empty 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X text 21 51 this is a port of IOhannes Zmoelnigs pan~ example; #X text 21 66 done by Frank Barknecht; #X text 183 17 flext tutorial \, (C)2002-2022 grrrr.org; #X obj 97 175 signal1~; #X msg 449 79 \; pd dsp 1; #X text 447 58 start DSP; #X obj 97 209 *~ 0.1; #X connect 0 0 9 0; #X connect 1 0 13 0; #X connect 3 0 13 1; #X connect 9 0 13 2; #X connect 13 0 16 0; #X connect 16 0 2 0; #X connect 16 0 2 1; flext-0-6-3/tutorial/pd/ex-signal2.pd000066400000000000000000000012541446466241400174210ustar00rootroot00000000000000#N canvas 41 125 593 252 12; #X obj 46 82 bng 25 250 50 0 empty empty empty 0 -6 0 8 #fce0c0 #000000 #000000; #X text 78 88 bang to get audio system parameters; #X obj 16 8 cnv 15 550 40 empty empty signal2 10 22 0 24 #fcac44 #000000 0; #X obj 45 186 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 137 186 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X text 40 203 samplerate; #X text 134 203 blocksize; #X text 251 20 flext tutorial \, (C)2002-2022 grrrr.org; #X obj 46 130 signal2~; #X msg 440 81 \; pd dsp 1; #X text 437 59 start DSP; #X connect 0 0 8 0; #X connect 8 0 3 0; #X connect 8 1 4 0; flext-0-6-3/tutorial/pd/ex-simple1.pd000066400000000000000000000006441446466241400174360ustar00rootroot00000000000000#N canvas 85 178 594 230 12; #X obj 16 8 cnv 15 550 40 empty empty simple1 10 22 0 24 #fcac44 #000000 0; #X obj 40 94 nbx 4 16 -999 999 0 0 empty empty input 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 40 171 nbx 7 16 -1e+37 1e+37 0 0 empty empty inverse 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 40 129 simple1; #X text 167 19 flext tutorial \, (C)2002-2022 grrrr.org; #X connect 1 0 3 0; #X connect 3 0 2 0; flext-0-6-3/tutorial/pd/ex-simple2.pd000066400000000000000000000011111446466241400174250ustar00rootroot00000000000000#N canvas 72 265 599 317 12; #X obj 42 196 simple2 3; #X text 121 177 default argument; #X obj 16 8 cnv 15 550 40 empty empty simple2 10 22 0 24 #fcac44 #000000 0; #X obj 41 110 nbx 4 16 -999 999 0 0 empty empty triggering 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 148 110 nbx 4 16 -999 999 0 0 empty empty non-triggering 0 -6 0 12 #fce0c0 #000000 #000000 0 256; #X obj 42 239 nbx 7 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X text 167 19 flext tutorial \, (C)2002-2022 grrrr.org; #X connect 0 0 5 0; #X connect 3 0 0 0; #X connect 4 0 0 1; flext-0-6-3/tutorial/pd/ex-simple3.pd000066400000000000000000000012371446466241400174370ustar00rootroot00000000000000#N canvas 111 93 647 342 12; #X msg 63 88 help; #X msg 112 138 born; #X msg 161 139 to; #X msg 203 141 hula; #X msg 217 178 hula 1; #X text 250 142 tag without argument; #X text 286 176 tag and argument; #X text 109 88 print a help message; #X obj 16 8 cnv 15 550 40 empty empty simple3 10 22 0 24 #fcac44 #000000 0; #X msg 217 209 symbol yeah; #X text 310 208 symbol message; #X text 174 18 flext tutorial \, (C)2002-2022 grrrr.org; #X obj 137 285 simple3; #X msg 217 240 other tag; #X text 296 240 other tag (unhandled); #X connect 0 0 12 0; #X connect 1 0 12 0; #X connect 2 0 12 0; #X connect 3 0 12 0; #X connect 4 0 12 0; #X connect 9 0 12 0; #X connect 13 0 12 0; flext-0-6-3/tutorial/pd/ex-sndobj1.pd000066400000000000000000000020161446466241400174170ustar00rootroot00000000000000#N canvas 92 67 584 392 12; #X obj 56 348 dac~; #X obj 15 8 cnv 15 550 40 empty empty sndobj1 10 22 0 24 #fcac44 #000000 0; #X text 170 285 adjust the volume; #X text 35 97 source; #X obj 171 268 hsl 128 15 0.01 1 1 0 empty empty empty -2 -6 0 8 #fce0c0 #000000 #000000 0 1; #X msg 160 148 shL \$1; #X msg 218 148 shR \$1; #X obj 244 84 hsl 128 15 0.5 2 1 0 empty empty empty -2 -6 0 8 #fce0c0 #000000 #000000 0 1; #X obj 244 104 hsl 128 15 0.5 2 1 0 empty empty empty -2 -6 0 8 #fce0c0 #000000 #000000 0 1; #X text 149 82 pitch left; #X text 149 102 pitch right; #X obj 31 119 osc~ 442; #X obj 32 304 *~ 0.3; #X obj 91 304 *~ 0.3; #X obj 32 226 sndobj1~ @shL 0.7 @shR 1.2; #X text 218 20 flext tutorial \, (C)2002-2022 grrrr.org; #X msg 454 82 \; pd dsp 1; #X text 454 61 start DSP; #X connect 4 0 12 1; #X connect 4 0 13 1; #X connect 5 0 14 0; #X connect 6 0 14 0; #X connect 7 0 5 0; #X connect 8 0 6 0; #X connect 11 0 14 0; #X connect 11 0 14 1; #X connect 12 0 0 0; #X connect 13 0 0 1; #X connect 14 0 12 0; #X connect 14 1 13 0; flext-0-6-3/tutorial/pd/ex-stk1.pd000066400000000000000000000007421446466241400167450ustar00rootroot00000000000000#N canvas 95 60 577 257 12; #X obj 66 186 dac~; #X obj 15 8 cnv 15 550 40 empty empty stk1 10 22 0 24 #fcac44 #000000 0; #X text 184 118 adjust the volume; #X obj 185 101 hsl 128 15 0.01 1 1 0 empty empty empty -2 -6 0 8 #fce0c0 #000000 #000000 0 1; #X obj 76 132 *~ 0.3; #X obj 76 86 stk1~; #X msg 425 87 \; pd dsp 1; #X text 425 65 start DSP; #X text 181 17 flext tutorial \, (C)2002-2022 grrrr.org; #X connect 3 0 4 1; #X connect 4 0 0 0; #X connect 4 0 0 1; #X connect 5 0 4 0; flext-0-6-3/tutorial/pd/ex-stk2.pd000066400000000000000000000016761446466241400167550ustar00rootroot00000000000000#N canvas 97 70 594 364 12; #X obj 48 319 dac~; #X obj 15 8 cnv 15 550 40 empty empty stk2 10 22 0 24 #fcac44 #000000 0; #X text 173 230 adjust the volume; #X obj 174 213 hsl 128 15 0.01 1 1 0 empty empty empty -2 -6 0 8 #fce0c0 #000000 #000000 0 1; #X obj 48 264 *~ 0.3; #X obj 48 216 stk2~; #X obj 105 264 *~ 0.3; #X msg 163 140 shL \$1; #X msg 221 140 shR \$1; #X obj 247 78 hsl 128 15 0.5 2 1 0 empty empty empty -2 -6 0 8 #fce0c0 #000000 #000000 0 1; #X obj 247 96 hsl 128 15 0.5 2 1 0 empty empty empty -2 -6 0 8 #fce0c0 #000000 #000000 0 1; #X text 152 74 pitch left; #X text 152 94 pitch right; #X obj 48 79 osc~ 442; #X text 180 21 flext tutorial \, (C)2002-2022 grrrr.org; #X msg 466 89 \; pd dsp 1; #X text 464 68 start DSP; #X connect 3 0 4 1; #X connect 3 0 6 1; #X connect 4 0 0 0; #X connect 5 0 4 0; #X connect 5 1 6 0; #X connect 6 0 0 1; #X connect 7 0 5 0; #X connect 8 0 5 0; #X connect 9 0 7 0; #X connect 10 0 8 0; #X connect 13 0 5 0; flext-0-6-3/tutorial/pd/ex-thread1.pd000066400000000000000000000026121446466241400174110ustar00rootroot00000000000000#N canvas 78 77 589 309 12; #X obj 39 91 bng 25 250 50 0 empty empty start 0 -6 0 8 #fce0c0 #000000 #000000; #X obj 131 185 delay 200; #X obj 228 185 delay 200; #X obj 325 185 delay 200; #X obj 421 185 delay 200; #X obj 16 8 cnv 15 550 40 empty empty thread1 10 22 0 24 #fcac44 #000000 0; #X obj 131 262 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 229 263 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 323 261 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 423 261 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 39 262 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 422 232 thread1; #X obj 324 231 thread1; #X obj 228 233 thread1; #X obj 130 231 thread1; #X obj 39 229 thread1; #X text 228 19 flext tutorial \, (C)2002-2022 grrrr.org; #X text 76 86 Click to start; #X text 76 107 When clicked twice \, the same thread is started a second time; #X text 76 129 The thread counts to 19 \, then stops; #X connect 0 0 1 0; #X connect 0 0 15 0; #X connect 1 0 2 0; #X connect 1 0 14 0; #X connect 2 0 3 0; #X connect 2 0 13 0; #X connect 3 0 4 0; #X connect 3 0 12 0; #X connect 4 0 11 0; #X connect 11 0 9 0; #X connect 12 0 8 0; #X connect 13 0 7 0; #X connect 14 0 6 0; #X connect 15 0 10 0; flext-0-6-3/tutorial/pd/ex-thread2.pd000066400000000000000000000024261446466241400174150ustar00rootroot00000000000000#N canvas 85 84 589 308 12; #X msg 84 188 stop; #X msg 255 192 stop; #X obj 199 99 bng 25 250 50 0 empty empty empty 0 -6 0 8 #fce0c0 #000000 #000000; #X obj 291 99 bng 25 250 50 0 empty empty empty 0 -6 0 8 #fce0c0 #000000 #000000; #X text 191 78 start; #X text 283 77 stop; #X msg 39 188 0; #X msg 210 192 0; #X msg 423 190 stop; #X msg 378 190 0; #X msg 133 188 text; #X msg 302 192 text; #X msg 470 190 text; #X obj 16 8 cnv 15 550 40 empty empty thread2 10 22 0 24 #fcac44 #000000 0; #X obj 65 264 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 231 265 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 403 267 nbx 5 16 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 12 #dce4fc #000000 #000000 0 256; #X obj 404 229 thread2 50; #X obj 232 229 thread2 15; #X obj 66 228 thread2 3; #X text 228 18 flext tutorial \, (C)2002-2022 grrrr.org; #X connect 0 0 19 0; #X connect 1 0 18 0; #X connect 2 0 6 0; #X connect 2 0 7 0; #X connect 2 0 9 0; #X connect 3 0 0 0; #X connect 3 0 1 0; #X connect 3 0 8 0; #X connect 6 0 19 0; #X connect 7 0 18 0; #X connect 8 0 17 0; #X connect 9 0 17 0; #X connect 10 0 19 0; #X connect 11 0 18 0; #X connect 12 0 17 0; #X connect 17 0 16 0; #X connect 18 0 15 0; #X connect 19 0 14 0; flext-0-6-3/tutorial/pd/ex-timer1.pd000066400000000000000000000041271446466241400172650ustar00rootroot00000000000000#N canvas 76 97 740 366 12; #X obj 16 8 cnv 15 700 40 empty empty timer1 10 22 0 24 #fcac44 #000000 0; #X obj 97 299 print; #X msg 51 101 resetA; #X msg 122 101 resetB; #X msg 206 144 oneshotA \$1; #X obj 244 101 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 #fcfcfc #000000 #000000 0 256; #X obj 206 102 bng 15 250 50 0 empty empty empty 0 -6 0 8 #14e814 #000000 #000000; #X obj 368 103 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 #fcfcfc #000000 #000000 0 256; #X obj 329 102 bng 15 250 50 0 empty empty empty 0 -6 0 8 #14e814 #000000 #000000; #X obj 493 103 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 #fcfcfc #000000 #000000 0 256; #X obj 462 102 bng 15 250 50 0 empty empty empty 0 -6 0 8 #14e814 #000000 #000000; #X obj 620 101 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10 #fcfcfc #000000 #000000 0 256; #X obj 599 101 bng 15 250 50 0 empty empty empty 0 -6 0 8 #14e814 #000000 #000000; #X msg 329 144 oneshotB \$1; #X msg 462 144 periodicA \$1; #X msg 599 143 periodicB \$1; #X text 65 79 reset timer; #X text 221 78 trigger single event; #X text 469 77 trigger periodic event; #X msg 404 215 gettime; #X msg 404 245 getostime; #X text 480 216 get time; #X text 501 245 get OS time; #X obj 97 244 timer1; #X obj 76 302 bng 15 250 50 0 empty empty empty 17 7 0 10 #c6ffc7 #000000 #000000; #X obj 153 268 list prepend set; #X obj 153 291 list trim; #X text 168 18 flext tutorial \, (C)2002-2022 grrrr.org; #X obj 205 121 f 1000; #X obj 328 121 f 2000; #X obj 461 121 f 500; #X obj 598 120 600; #X msg 153 313; #X connect 2 0 23 0; #X connect 3 0 23 0; #X connect 4 0 23 0; #X connect 5 0 28 1; #X connect 6 0 28 0; #X connect 7 0 29 1; #X connect 8 0 29 0; #X connect 9 0 30 1; #X connect 10 0 30 0; #X connect 11 0 31 1; #X connect 12 0 31 0; #X connect 13 0 23 0; #X connect 14 0 23 0; #X connect 15 0 23 0; #X connect 19 0 23 0; #X connect 20 0 23 0; #X connect 23 0 1 0; #X connect 23 0 24 0; #X connect 23 0 25 0; #X connect 23 1 1 0; #X connect 23 1 25 0; #X connect 25 0 26 0; #X connect 26 0 32 0; #X connect 28 0 4 0; #X connect 29 0 13 0; #X connect 30 0 14 0; #X connect 31 0 15 0; flext-0-6-3/tutorial/pd/test.pd000066400000000000000000000010771446466241400164320ustar00rootroot00000000000000#N canvas 52 68 415 253 12; #X msg 194 190 \; pd quit; #X msg 304 76 \; pd dsp 1; #N canvas 658 95 450 300 test 0; #X restore 193 74 pd test; #X obj 26 41 r r; #X msg 27 189 \; pd-test obj 10 10 \$1; #X text 20 11 This is for CI testing purposes; #X obj 26 88 route del obj quit; #X obj 303 52 loadbang; #X obj 195 141 delay; #X obj 27 163 list; #X obj 27 136 delay; #X obj 26 64 list trim; #X connect 3 0 11 0; #X connect 6 0 10 0; #X connect 6 1 9 1; #X connect 6 2 8 0; #X connect 7 0 1 0; #X connect 8 0 0 0; #X connect 9 0 4 0; #X connect 10 0 9 0; #X connect 11 0 6 0; flext-0-6-3/tutorial/pd/test.sh000077500000000000000000000012731446466241400164420ustar00rootroot00000000000000#!/bin/bash # This script tests the tutorial externals in gitlab CI root="$1" pd="${2:-pd}" patches="${root}/tutorial/pd" testpatch="${patches}/test.pd" logfile="${patches}/test.log" for f in ${root}/tutorial/?_*/*.pd_*; do p="${f%/*}" pp="${p##*_}" ext="${f##*/}" n="${ext%%.*}" ex="${patches}/ex-${pp}" echo Testing object $n with example patch $ex if ! [ -f ${ex}.pd ]; then echo Example patch $ex not found, testing mere object $n ex=$n fi if ! "$pd" -nort -noprefs -noaudio -nomidi -nogui -path "$p" -path "$patches" -open "$testpatch" -send "r obj $ex" -send "r del 100" -send "r quit 1000" &> "$logfile" || grep error "$logfile" then exit -1 fi done flext-0-6-3/tutorial/readme.txt000066400000000000000000000016641446466241400165230ustar00rootroot00000000000000flext - C++ layer for Max/MSP and pd (pure data) externals tutorial examples Copyright (c) 2001-2022 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. ---------------------------------------------------------------------------- These are a few examples to demonstrate some flext features. Contribution of examples to the package is higly appreciated! ---------------------------------------------------------------------------- The recommended order to go through the tutorial examples is the following: 1) 1_simple* 2) 2_adv* 3) 3_attr* 4) 4_timer*, 4_bind*, 4_buffer* 5) 5_signal* 6) 6_lib* 7) 7_thread* and, if needed 8) 8_sndobj* and/or 8_stk* if you choose to compile with SndObj support, the respective library can be found here: http://sndobj.sourceforge.net/sndobj.html or here: https://github.com/johnglover/sndobj