pax_global_header00006660000000000000000000000064127672336030014523gustar00rootroot0000000000000052 comment=59e9f9bb694ea07a526d610821403f1443ef7f68 pd-miXedSon-0.2beta3/000077500000000000000000000000001276723360300144325ustar00rootroot00000000000000pd-miXedSon-0.2beta3/LICENSE.txt000066400000000000000000000030411276723360300162530ustar00rootroot00000000000000This software is copyrighted by Miller Puckette and others. The following terms (the "Standard Improved BSD License") apply to all files associated with the software unless explicitly disclaimed in individual files: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. pd-miXedSon-0.2beta3/Makefile000066400000000000000000000347401276723360300161020ustar00rootroot00000000000000# Makefile for pure data externals in lib cyclone lib.name = cyclone # for the MINGW which has the timespec struct defined twice cflags = -Ishared -DHAVE_STRUCT_TIMESPEC uname := $(shell uname -s) ifeq (MINGW,$(findstring MINGW,$(uname))) exe.extension = .exe endif ################################################################################ ### hammer ##################################################################### ################################################################################ # common sources for hammer types hloud := \ shared/common/loud.c hfitter := \ shared/common/loud.c \ shared/common/fitter.c hforky := \ shared/common/loud.c \ shared/unstable/forky.c hfragile := \ shared/common/loud.c \ shared/unstable/fragile.c hgrow := \ shared/common/grow.c \ shared/common/loud.c hgrowfitter := \ shared/common/grow.c \ shared/common/loud.c \ shared/common/fitter.c hfile := \ shared/hammer/file.c \ shared/common/loud.c \ shared/common/os.c \ shared/common/fitter.c \ shared/unstable/forky.c hrand := \ shared/common/rand.c \ shared/common/loud.c hrandfile := \ shared/common/rand.c \ shared/hammer/file.c \ shared/common/loud.c \ shared/common/os.c \ shared/common/fitter.c \ shared/unstable/forky.c hrandgrow := \ shared/common/rand.c \ shared/common/grow.c \ shared/common/loud.c \ shared/common/fitter.c hrandgrowfile := \ shared/common/rand.c \ shared/common/grow.c \ shared/hammer/file.c \ shared/common/loud.c \ shared/common/os.c \ shared/unstable/forky.c htree := \ shared/hammer/tree.c \ shared/common/loud.c htreefilevefl := \ shared/hammer/tree.c \ shared/hammer/file.c \ shared/common/vefl.c \ shared/common/loud.c \ shared/common/os.c \ shared/unstable/forky.c \ shared/unstable/fragile.c hgui := \ shared/hammer/gui.c \ shared/common/loud.c hseq := \ shared/common/mifi.c \ shared/hammer/file.c \ shared/common/grow.c \ shared/common/loud.c \ shared/common/os.c \ shared/common/fitter.c \ shared/unstable/forky.c # hammer classes accum.class.sources := hammer/accum.c $(hplain) acos.class.sources := hammer/acos.c $(hplain) active.class.sources := hammer/active.c $(hgui) anal.class.sources := hammer/anal.c $(hloud) Append.class.sources := hammer/Append.c $(hgrowfitter) asin.class.sources := hammer/asin.c $(hplain) bangbang.class.sources := hammer/bangbang.c $(hfitter) bondo.class.sources := hammer/bondo.c $(hgrow) Borax.class.sources := hammer/Borax.c $(hloud) Bucket.class.sources := hammer/Bucket.c $(hplain) buddy.class.sources := hammer/buddy.c $(hgrow) capture.class.sources := hammer/capture.c $(hfile) cartopol.class.sources := hammer/cartopol.c $(hplain) Clip.class.sources := hammer/Clip.c $(hgrow) coll.class.sources := hammer/coll.c $(hfile) comment.class.sources := hammer/comment.c $(hforky) cosh.class.sources := hammer/cosh.c $(hplain) counter.class.sources := hammer/counter.c $(hfitter) cycle.class.sources := hammer/cycle.c $(hfitter) decide.class.sources := hammer/decide.c $(hloud) Decode.class.sources := hammer/Decode.c $(hfitter) drunk.class.sources := hammer/drunk.c $(hrand) flush.class.sources := hammer/flush.c $(hplain) forward.class.sources := hammer/forward.c $(hplain) fromsymbol.class.sources := hammer/fromsymbol.c $(hplain) funbuff.class.sources := hammer/funbuff.c $(htreefilevefl) funnel.class.sources := hammer/funnel.c $(hgrow) gate.class.sources := hammer/gate.c $(hfitter) grab.class.sources := hammer/grab.c $(hfragile) Histo.class.sources := hammer/Histo.c $(hloud) iter.class.sources := hammer/iter.c $(hgrow) match.class.sources := hammer/match.c $(hgrow) maximum.class.sources := hammer/maximum.c $(hfitter) mean.class.sources := hammer/mean.c $(hplain) midiflush.class.sources := hammer/midiflush.c $(hplain) midiformat.class.sources := hammer/midiformat.c $(hplain) midiparse.class.sources := hammer/midiparse.c $(hplain) minimum.class.sources := hammer/minimum.c $(hfitter) mousefilter.class.sources := hammer/mousefilter.c $(hgui) MouseState.class.sources := hammer/MouseState.c $(hgui) mtr.class.sources := hammer/mtr.c $(hfile) next.class.sources := hammer/next.c $(hplain) offer.class.sources := hammer/offer.c $(htree) onebang.class.sources := hammer/onebang.c $(hplain) past.class.sources := hammer/past.c $(hgrowfitter) Peak.class.sources := hammer/Peak.c $(hplain) poltocar.class.sources := hammer/poltocar.c $(hplain) prepend.class.sources := hammer/prepend.c $(hgrowfitter) prob.class.sources := hammer/prob.c $(hrandfile) pv.class.sources := hammer/pv.c $(hgrow) seq.class.sources := hammer/seq.c $(hseq) sinh.class.sources := hammer/sinh.c $(hplain) speedlim.class.sources := hammer/speedlim.c $(hgrow) spell.class.sources := hammer/spell.c $(hloud) split.class.sources := hammer/split.c $(hplain) spray.class.sources := hammer/spray.c $(hloud) sprintf.class.sources := hammer/sprintf.c $(hloud) substitute.class.sources := hammer/substitute.c $(hgrow) sustain.class.sources := hammer/sustain.c $(hplain) switch.class.sources := hammer/switch.c $(hfitter) Table.class.sources := hammer/Table.c $(hrandgrowfile) tanh.class.sources := hammer/tanh.c $(hplain) testmess.class.sources := hammer/testmess.c $(hfragile) thresh.class.sources := hammer/thresh.c $(hgrow) TogEdge.class.sources := hammer/TogEdge.c $(hloud) tosymbol.class.sources := hammer/tosymbol.c $(hgrow) Trough.class.sources := hammer/Trough.c $(hplain) universal.class.sources := hammer/universal.c $(hfragile) urn.class.sources := hammer/urn.c $(hrandgrow) Uzi.class.sources := hammer/Uzi.c $(hplain) xbendin2.class.sources := hammer/xbendin2.c $(hplain) xbendin.class.sources := hammer/xbendin.c $(hplain) xbendout2.class.sources := hammer/xbendout2.c $(hplain) xbendout.class.sources := hammer/xbendout.c $(hplain) xnotein.class.sources := hammer/xnotein.c $(hplain) xnoteout.class.sources := hammer/xnoteout.c $(hplain) zl.class.sources := hammer/zl.c $(hgrow) ################################################################################ ### sickle ##################################################################### ################################################################################ # common sources for sickle types ssic := \ shared/sickle/sic.c \ shared/common/loud.c sforky := \ shared/sickle/sic.c \ shared/common/loud.c \ shared/unstable/forky.c sfragile := \ shared/sickle/sic.c \ shared/common/loud.c \ shared/unstable/fragile.c sfragilefitter := \ shared/sickle/sic.c \ shared/common/loud.c \ shared/common/fitter.c \ shared/unstable/fragile.c sgrow := \ shared/common/grow.c \ shared/sickle/sic.c \ shared/common/loud.c sgrowclc := \ shared/common/grow.c \ shared/common/clc.c \ shared/sickle/sic.c \ shared/common/loud.c sgrowforky := \ shared/common/grow.c \ shared/sickle/sic.c \ shared/common/loud.c \ shared/common/fitter.c \ shared/unstable/forky.c svefl := \ shared/common/vefl.c \ shared/sickle/sic.c \ shared/common/loud.c \ shared/unstable/fragile.c sarsic := \ shared/sickle/sic.c \ shared/sickle/arsic.c \ shared/common/vefl.c \ shared/common/loud.c \ shared/unstable/fragile.c sarsicfitter := \ shared/sickle/sic.c \ shared/sickle/arsic.c \ shared/common/vefl.c \ shared/common/loud.c \ shared/common/fitter.c \ shared/unstable/fragile.c sfile := \ shared/hammer/file.c \ shared/sickle/sic.c \ shared/common/loud.c \ shared/common/os.c \ shared/unstable/forky.c # special case: sickle but not tilde (see class linedrive) splainnotilde := \ shared/common/loud.c \ shared/common/fitter.c # sickle classes abs~.class.sources := sickle/abs.c $(ssic) acos~.class.sources := sickle/acos.c $(ssic) acosh~.class.sources := sickle/acosh.c $(ssic) allpass~.class.sources := sickle/allpass.c $(ssic) asin~.class.sources := sickle/asin.c $(ssic) asinh~.class.sources := sickle/asinh.c $(ssic) atan2~.class.sources := sickle/atan2.c $(ssic) atan~.class.sources := sickle/atan.c $(ssic) atanh~.class.sources := sickle/atanh.c $(ssic) average~.class.sources := sickle/average.c $(ssic) avg~.class.sources := sickle/avg.c $(ssic) bitand~.class.sources := sickle/bitand.c $(sforky) bitnot~.class.sources := sickle/bitnot.c $(ssic) bitor~.class.sources := sickle/bitor.c $(sforky) bitshift~.class.sources := sickle/bitshift.c $(ssic) bitxor~.class.sources := sickle/bitxor.c $(sforky) buffir~.class.sources := sickle/buffir.c $(sarsicfitter) capture~.class.sources := sickle/capture.c $(sfile) cartopol~.class.sources := sickle/cartopol.c $(sfragile) change~.class.sources := sickle/change.c $(ssic) click~.class.sources := sickle/click.c $(sgrow) Clip~.class.sources := sickle/Clip.c $(ssic) comb~.class.sources := sickle/comb.c $(ssic) cosh~.class.sources := sickle/cosh.c $(ssic) cosx~.class.sources := sickle/cosx.c $(ssic) count~.class.sources := sickle/count.c $(ssic) curve~.class.sources := sickle/curve.c $(sgrowclc) cycle~.class.sources := sickle/cycle.c $(svefl) delay~.class.sources := sickle/delay.c $(ssic) delta~.class.sources := sickle/delta.c $(ssic) deltaclip~.class.sources := sickle/deltaclip.c $(ssic) edge~.class.sources := sickle/edge.c $(ssic) frameaccum~.class.sources := sickle/frameaccum.c $(sgrow) framedelta~.class.sources := sickle/framedelta.c $(sgrow) index~.class.sources := sickle/index.c $(sarsic) kink~.class.sources := sickle/kink.c $(ssic) Line~.class.sources := sickle/Line.c $(sgrow) linedrive.class.sources := sickle/linedrive.c $(splainnotilde) log~.class.sources := sickle/log.c $(ssic) lookup~.class.sources := sickle/lookup.c $(sarsic) lores~.class.sources := sickle/lores.c $(ssic) matrix~.class.sources := sickle/matrix.c $(sfragilefitter) maximum~.class.sources := sickle/maximum.c $(ssic) minimum~.class.sources := sickle/minimum.c $(ssic) minmax~.class.sources := sickle/minmax.c $(ssic) mstosamps~.class.sources := sickle/mstosamps.c $(ssic) onepole~.class.sources := sickle/onepole.c $(ssic) overdrive~.class.sources := sickle/overdrive.c $(ssic) peakamp~.class.sources := sickle/peakamp.c $(ssic) peek~.class.sources := sickle/peek.c $(sarsic) phasewrap~.class.sources := sickle/phasewrap.c $(ssic) pink~.class.sources := sickle/pink.c $(ssic) play~.class.sources := sickle/play.c $(sarsic) poke~.class.sources := sickle/poke.c $(sarsic) poltocar~.class.sources := sickle/poltocar.c $(sfragile) pong~.class.sources := sickle/pong.c $(sforky) pow~.class.sources := sickle/pow.c $(ssic) rampsmooth~.class.sources := sickle/rampsmooth.c $(ssic) rand~.class.sources := sickle/rand.c $(ssic) record~.class.sources := sickle/record.c $(sarsic) reson~.class.sources := sickle/reson.c $(ssic) sah~.class.sources := sickle/sah.c $(ssic) sampstoms~.class.sources := sickle/sampstoms.c $(ssic) Scope~.class.sources := sickle/Scope.c $(sgrowforky) sinh~.class.sources := sickle/sinh.c $(ssic) sinx~.class.sources := sickle/sinx.c $(ssic) slide~.class.sources := sickle/slide.c $(ssic) Snapshot~.class.sources := sickle/Snapshot.c $(ssic) spike~.class.sources := sickle/spike.c $(ssic) svf~.class.sources := sickle/svf.c $(ssic) tanh~.class.sources := sickle/tanh.c $(ssic) tanx~.class.sources := sickle/tanx.c $(ssic) teeth~.class.sources := sickle/teeth.c $(ssic) train~.class.sources := sickle/train.c $(ssic) trapezoid~.class.sources := sickle/trapezoid.c $(ssic) triangle~.class.sources := sickle/triangle.c $(ssic) vectral~.class.sources := sickle/vectral.c $(ssic) wave~.class.sources := sickle/wave.c $(sarsic) zerox~.class.sources := sickle/zerox.c $(ssic) nettles.class.sources := shadow/nettles.c $(ssic) datafiles = \ $(wildcard help/*-help.pd) \ help/dspSwitch~.pd \ help/output~.pd \ help/test.mid \ help/voice.wav \ LICENSE.txt \ README.md \ cyclone-meta.pd ################################################################################ ### pdlibbuilder ############################################################### ################################################################################ # Include Makefile.pdlibbuilder from this directory, or else from central # externals directory in pd-extended configuration. externalsdir = ../.. include $(firstword $(wildcard Makefile.pdlibbuilder \ $(externalsdir)/Makefile.pdlibbuilder)) ################################################################################ ### cyclone extra targets ###################################################### ################################################################################ install: install-aliases install-cyclist # on Linux, add symbolic links for lower case aliases install-aliases: all ifeq ($(uname), Linux) $(INSTALL_DIR) -v $(installpath) cd $(installpath); \ ln -s -f Append.$(extension) append.$(extension); \ ln -s -f Append-help.pd append-help.pd; \ ln -s -f Borax.$(extension) borax.$(extension); \ ln -s -f Borax-help.pd borax-help.pd; \ ln -s -f Bucket.$(extension) bucket.$(extension); \ ln -s -f Bucket-help.pd bucket-help.pd; \ ln -s -f Clip.$(extension) clip.$(extension); \ ln -s -f Clip-help.pd clip-help.pd; \ ln -s -f Decode.$(extension) decode.$(extension); \ ln -s -f Decode-help.pd decode-help.pd; \ ln -s -f Histo.$(extension) histo.$(extension); \ ln -s -f Histo-help.pd histo-help.pd; \ ln -s -f MouseState.$(extension) mousestate.$(extension); \ ln -s -f MouseState-help.pd mousestate-help.pd; \ ln -s -f Peak.$(extension) peak.$(extension); \ ln -s -f Peak-help.pd peak-help.pd; \ ln -s -f Table.$(extension) table.$(extension); \ ln -s -f Table-help.pd table-help.pd; \ ln -s -f TogEdge.$(extension) togedge.$(extension); \ ln -s -f TogEdge-help.pd togedge-help.pd; \ ln -s -f Trough.$(extension) trough.$(extension); \ ln -s -f Trough-help.pd trough-help.pd; \ ln -s -f Uzi.$(extension) uzi.$(extension); \ ln -s -f Uzi-help.pd uzi-help.pd; \ ln -s -f Clip~.$(extension) clip~.$(extension); \ ln -s -f Clip~-help.pd clip~-help.pd; \ ln -s -f Line~.$(extension) line~.$(extension); \ ln -s -f Line~-help.pd line~-help.pd; \ ln -s -f Scope~.$(extension) scope~.$(extension); \ ln -s -f Scope~-help.pd scope~-help.pd; \ ln -s -f Snapshot~.$(extension) snapshot~.$(extension); \ ln -s -f Snapshot~-help.pd snapshot~-help.pd endif all: cyclist$(exe.extension) SHARED_DIR=shared cyclist$(exe.extension): $(SHARED_DIR)/common/binport.c \ $(SHARED_DIR)/common/lex.c \ $(SHARED_DIR)/unstable/standalone.c $(CC) -I$(SHARED_DIR) -DMIXED_STANDALONE $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^ install-cyclist: cyclist$(exe.extension) $(INSTALL_DIR) -v "$(installpath)" $(INSTALL_PROGRAM) cyclist* "$(installpath)" clean: clean-cyclist clean-cyclist: rm -f cyclist$(exe.extension) rm -f $(SHARED_DIR)/common/lex.o rm -f $(SHARED_DIR)/unstable/standalone.o rm -f $(SHARED_DIR)/common/binport.o pd-miXedSon-0.2beta3/Makefile.pdlibbuilder000066400000000000000000001173211276723360300205370ustar00rootroot00000000000000# Makefile.pdlibbuilder dated 2016-06-26 version = 0.2.5 # Helper makefile for Pure Data external libraries. # Written by Katja Vetter March-June 2015 for the public domain. No warranties. # Inspired by Hans Christoph Steiner's Makefile Template and Stephan Beal's # ShakeNMake. # # GNU make version >= 3.81 required. # # #=== characteristics =========================================================== # # # - defines build settings based on autodetected OS and architecture # - defines rules to build Pd class- or lib executables from C or C++ sources # - defines rules for libdir installation # - defines convenience targets for developer and user # - evaluates implicit dependencies for non-clean builds # # #=== basic usage =============================================================== # # # In your Makefile, define your Pd lib name and class files, and include # Makefile.pdlibbuilder at the end of the Makefile. Like so: # # ________________________________________________________________________ # # # Makefile for mylib # # lib.name = mylib # # class.sources = myclass1.c myclass2.c # # datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt # # include Makefile.pdlibbuilder # ________________________________________________________________________ # # # For files in class.sources it is assumed that class basename == source file # basename. The default target builds all classes as individual executables # with Pd's default extension for the platform. For anything more than the # most basic usage, continue reading. # # #=== list of Makefile.pdlibbuilder API variables =============================== # # # Variables available for definition in your library Makefile: # # - lib.name # - lib.setup.sources # - class.sources # - common.sources # - shared.sources # - .class.sources # - .class.ldflags # - .class.ldlibs # - cflags # - ldflags # - ldlibs # - datafiles # - datadirs # - makefiles # - makefiledirs # - externalsdir # # Optional multiline defines evaluated per operating system: # # - forLinux # - forDarwin # - forWindows # # # Variables avaialable for (re)definition via command arguments: # # - pdbinpath (Windows only) # - pdincludepath # - DESTDIR # - prefix # - libdir # - pkglibdir # - CPPFLAGS # - CFLAGS # - LDFLAGS # - CC # - CXX # - INSTALL # - INSTALL_PROGRAM # - INSTALL_DATA # - INSTALL_DIR # # Variables available for your makefile or as command argument: # # - objectsdir # - make-lib-executable # - suppress-wunused # # #=== descriptions of Makefile.pdlibbuilder API variables ======================= # # # lib.name: # Name of the library directory as it will be installed / distributed. Also the # name of the lib executable in the case where all classes are linked into # a single binary. # # lib.setup.sources: # Source file(s) (C or C++) which must be compiled only when linking all classes # into a single lib binary. # # class.sources: # All sources files (C or C++) for which the condition holds that # class name == source file basename. # # .class.sources: # Source file(s) (C or C++) specific to class . Use this for # multiple-source classes or when class name != source file basename. # # common.sources: # Source file(s) which must be statically linked to each class in the library. # # shared.sources: # Source file(s) (C or C++) to build a shared dynamic link lib, to be linked # with all class executables. # # cflags, ldflags, ldlibs: # Define cflags (preprocessor&compiler), ldflags (linker) and ldlibs (dynamic # link libs) for the whole library. These flags are added to platform-specific # flags defined by Makefile.pdlibbuilder. # # .class.ldflags and .class.ldlibs: # Define ldflags resp. ldlibs specific to class . These flags are # added to platform-specific flags defined by Makefile.pdlibbuilder, and flags # defined in your Makefile for the whole library. Note: cflags can not be # defined per class in the current implementation. # # datafiles and datadirs: # All extra files you want to include in binary distributions of the # library: abstractions and help patches, example patches, meta patch, readme # and license texts, manuals, sound files, etcetera. Use 'datafiles' for all # files that should go into your lib rootdir and 'datadirs' for complete # directories you want to copy from source to distribution. # # externalsdir: # Relative path to directory 'externals' in the context of pd-extended SVN, or # any other centralized build layout for multiple libraries. Default value # is '..', meaning the direct parent. The value is used in search paths for # pd core components (header files, and executable in the case of Windows). # # forLinux, forDarwin, forWindows: # Shorthand for 'variable definitions for Linux only' etc. Use like: # define forLinux # cflags += -DLINUX # class.sources += linuxthing.c # endef # # makefiles and makefiledirs: # Extra makefiles or directories with makefiles that should be made in sub-make # processes. # # pdbinpath: # For Windows only. Directory where pd.dll can be found for linking. # # pdincludepath: # Directory where Pd API m_pd.h can be found, and other Pd header files. # # DESTDIR, prefix, libdir: # Components of the path for installation as conventionally used on Linux. # # pkglibdir: # Base path for installation of Pd library directories. Default is specified # per OS, see section about paths below. # # objectsdir: # Alias of pkglibdir. Can be defined in your makefile to enable project- # dependent relative install locations. # # CPPFLAGS: # Preprocessor flags which are not strictly required for building. # # CFLAGS: # Compiler flags which are not strictly required for building. Compiler flags # defined by Makefile.pdlibbuilder for warning, optimization and architecture # specification are overriden by CFLAGS. # # LDFLAGS: # Linker flags which are not strictly required for building. Linker flags # defined by Makefile.pdlibbuilder for architecture specification are overriden # by LDFLAGS. # # CC and CXX: # C and C++ compiler programs as defined in your build environment. # # INSTALL, INSTALL_PROGRAM, INSTALL_DATA, INSTALL_DIR: # Definitions of install program, may be overriden via command argument. # # make-lib-executable: # When this variable is defined 'yes' in your makefile or as command argument, # Makefile.pdlibbuilder will try to build all classes into a single library # executable (but it will force exit if lib.setup.sources is undefined). # If your makefile defines 'make-lib-executable=yes' as the library default, # this can still be overriden with 'make-lib-executable=no' as command argument # to build individual class executables (the Makefile.pdlibbuilder default.) # # suppress-wunused: # When this variable is defined ('yes' or any other value), -Wunused-variable, # -Wunused-parameter, -Wunused-value and -Wunused-function are suppressed, # but the other warnings from -Wall are retained. # # #=== paths ===================================================================== # # # Source files in directories other than current working directory must be # prefixed with their relative path. Do not rely on VPATH or vpath. # Object (.o) files are built in the directory of their source files. # Executables are built in current working directory. # # Variable 'pdincludepath' stores a location where m_pd.h is expected to reside. # Locations where Makefile.pdlibbuilder tries to find it, in order of priority: # # any OS: $(externalsdir)../pd/src # # Linux: /usr/include/pdextended # /usr/include/pd # # OSX: /Applications/Pd-extended.app/Contents/Resources/include/pdextended # /Applications/Pd.app/Contents/Resources/src # # Windows: %PROGRAMFILES%/pd/include/pdextended # %PROGRAMFILES%/pd/src # # The path for installation of all library components is constructed as: # # installpath := $(DESTDIR)$(objectsdir)/$(lib.name) # # Default for 'objectsdir' is defined per platform and follows this convention: # https://puredata.info/docs/faq/how-do-i-install-externals-and-help-files # # Linux: /usr/local/lib/pd-externals # OSX: ~/Library/Pd # Windows: %APPDATA%/Pd # # The rationale for not installing to ~/pd-externals by default on Linux # is that some people share the home dir between 32 and 64 bit installations. # # #=== targets =================================================================== # # # all: build $(executables) plus optional post target # post: target to build after $(executables) # alldebug: build all with -g option turned on for debug symbols # : force clean build of an individual class # .pre: make preprocessor output file in current working directory # .lst: make asm/source output file in current working directory # # install: install executables and data files # clean: remove build products from source tree # # help: print help text # vars: print makefile variables # allvars: print all variables # depend: print generated prerequisites # coffee: dummy target # # Variable $(executables) expands to class executables plus optional shared lib, # or alternatively to single lib executable when make-lib-executable=true. # Targets pre and post can be defined by library makefile. Make sure to include # Makefile.pdlibbuilder first so default target all will not be redefined. # # #=== Pd-extended libdir concept ================================================ # # # For libdir layout as conceived by Hans-Christoph Steiner, see: # # https://puredata.info/docs/developer/Libdir # # Files README.txt, LICENSE.txt and -meta.pd are part of the libdir # convention. Help patches for each class and abstraction are supposed to be # available. Makefile.pdlibbuilder does not force the presence of these files # however. It does not automatically include such files in libdir installations. # Data files you want to include in distributions must be defined explicitly in # your Makefile. # # #=== Makefile.pdlibbuilder syntax conventions ================================== # # # Makefile.pdlibbuilder variable names are lower case. Default make variables, # environment variables, and standard user variables (CC, CXX, CFLAGS, DESTDIR) # are upper case. Use target 'allvars' to print all variables and their values. # # 'Fields' in data variables are separated by dots, like in 'foo.class.sources'. # Words in variables expressing a function or command are separated by dashes, # like in 'make-lib-executable'. # # #=== useful make options ======================================================= # # # Use 'make -d ' to print debug details of the make process. # Use 'make -p ' to print make's database. # # #=== TODO ====================================================================== # # # - decide whether to use -static-libgcc or shared dll in MinGW # - cygwin support # - android support # - Windows 64 bit support # - figure out how to handle '$' in filenames # - add makefile template targets dpkg-source dist libdir distclean tags? # # #=== end of documentation sections ============================================= # # ################################################################################ ################################################################################ ################################################################################ # GNU make version 3.81 (2006) or higher is required because of the following: # - function 'info' # - variable '.DEFAULT_GOAL' # force exit when make version is < 3.81 ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))), 3.81) $(error GNU make version 3.81 or higher is required) endif # Relative path to externals root dir in multi-lib source tree like # pd-extended SVN. Default is parent of current working directory. May be # defined differently in including makefile. This variable is used to probe for # paths. externalsdir ?= .. # variable you can use to check if Makefile.pdlibbuilder is already included Makefile.pdlibbuilder = true ################################################################################ ### variables: library name and version ######################################## ################################################################################ # strip possibles spaces from lib.name, they mess up calculated file names lib.name := $(strip $(lib.name)) # if meta file exists, check library version metafile := $(wildcard $(lib.name)-meta.pd) ifdef metafile lib.version := $(shell sed -n \ 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' \ $(metafile)) endif ################################################################################ ### variables: files ########################################################### ################################################################################ #=== sources =================================================================== # (re)define .class.sources using file names in class.sources define add-class-source $(notdir $(basename $v)).class.sources += $v endef $(foreach v, $(class.sources), $(eval $(add-class-source))) # derive class names from .class.sources variables sourcevariables := $(filter %.class.sources, $(.VARIABLES)) classes := $(basename $(basename $(sourcevariables))) # accumulate all source files specified in makefile classes.sources := $(sort $(foreach v, $(sourcevariables), $($v))) all.sources := $(classes.sources) $(lib.setup.sources) \ $(shared.sources) $(common.sources) #=== object files ============================================================== # construct object filenames from all C and C++ source file names classes.objects := $(addsuffix .o, $(basename $(classes.sources))) common.objects := $(addsuffix .o, $(basename $(common.sources))) shared.objects := $(addsuffix .o, $(basename $(shared.sources))) lib.setup.objects := $(addsuffix .o, $(basename $(lib.setup.sources))) all.objects = $(classes.objects) $(common.objects) $(shared.objects) \ $(lib.setup.objects) #=== executables =============================================================== # use recursive variables here because executable extension is not yet known # construct class executable names from class names classes.executables = $(addsuffix .$(extension), $(classes)) # construct shared lib executable name if shared sources are defined ifdef shared.sources shared.lib = lib$(lib.name).$(shared.extension) else shared.lib = endif ################################################################################ ### variables per platform ##################################################### ################################################################################ #=== flags per architecture ==================================================== # Set architecture-dependent cflags, mainly for Linux. For Mac and Windows, # arch.c.flags are overriden below. machine := $(shell uname -m) # Raspberry Pi 1st generation ifeq ($(machine), armv6l) arch.c.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard endif # Beagle, Udoo, RPi2 etc. ifeq ($(machine), armv7l) arch.c.flags = -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard endif # Intel 32 bit, build with SSE and SSE2 instructions ifeq ($(findstring $(machine), i386 i686), $(machine)) arch.c.flags = -march=pentium4 -mfpmath=sse -msse -msse2 endif # Intel/AMD 64 bit, build with SSE, SSE2 and SSE3 instructions ifeq ($(findstring $(machine), ia64 x86_64), $(machine)) arch.c.flags = -march=core2 -mfpmath=sse -msse -msse2 -msse3 endif #=== operating system ========================================================== # The following systems are defined: Linux, Darwin, Windows. GNU and # GNU/kFreeBSD are treated as Linux to get the same options. System-specific # multiline defines (optionally set in library makefile) are conditionally # evaluated here. uname := $(shell uname) ifeq ($(findstring $(uname), Linux GNU GNU/kFreeBSD), $(uname)) system = Linux $(eval $(forLinux)) endif ifeq ($(uname), Darwin) system = Darwin $(eval $(forDarwin)) endif ifeq ($(findstring MINGW, $(uname)), MINGW) system = Windows $(eval $(forWindows)) endif # TODO: Cygwin, Android #=== flags and paths for Linux ================================================= ifeq ($(system), Linux) prefix = /usr/local libdir := $(prefix)/lib pkglibdir = $(libdir)/pd-externals pdincludepath := $(firstword $(wildcard \ $(externalsdir)/../pd/src \ /usr/include/pdextended \ /usr/include/pd)) extension = pd_linux cpp.flags := -DUNIX c.flags := -fpic c.ldflags := -rdynamic -shared -fpic -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags c.ldlibs := -lc -lm cxx.flags := -fpic -fcheck-new cxx.ldflags := -rdynamic -shared -fpic -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags cxx.ldlibs := -lc -lm -lstdc++ shared.extension = so shared.ldflags := -rdynamic -fpic -shared -Wl,-soname,$(shared.lib) stripflags = --strip-unneeded -R .note -R .comment endif #=== flags and paths for Darwin ================================================ # On OSX we try to build fat binaries by default. It is assumed that OSX i386 # can build for ppc and OSX x86_64 can't. TODO: try to refine this condition. # LLVM-clang doesn't support -fcheck-new, therefore this flag is omitted for # OSX x86_64. ifeq ($(system), Darwin) pkglibdir = $(HOME)/Library/Pd pdincludepath := $(firstword $(wildcard \ $(externalsdir)/../pd/src \ /Applications/Pd-extended*.app/Contents/Resources/include/pdextended \ /Applications/Pd*.app/Contents/Resources/src)) extension = pd_darwin cpp.flags := -DUNIX -DMACOSX -I /sw/include c.flags := c.ldflags := -undefined suppress -flat_namespace -bundle c.ldlibs := -lc cxx.ldflags := -undefined suppress -flat_namespace -bundle cxx.ldlibs := -lc shared.extension = dylib shared.ldflags = -dynamiclib -undefined dynamic_lookup \ -install_name @loader_path/$(shared.lib) \ -compatibility_version 1 -current_version 1.0 stripflags = -x ifeq ($(machine), i386) cxx.flags := -fcheck-new arch.c.flags := -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 arch.ld.flags := -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 endif ifeq ($(machine), x86_64) arch.c.flags := -arch i386 -arch x86_64 -mmacosx-version-min=10.5 arch.ld.flags := -arch i386 -arch x86_64 -mmacosx-version-min=10.5 endif endif #=== flags and paths for Windows =============================================== # Standard paths on Windows contain spaces, and GNU make functions treat such # paths as lists, with unintended effects. Therefore we must use shell function # ls instead of make's wildcard, and probe for each standard path individually. # Using double quotes around paths with spaces is obligatory. Since some path # variables are assembled or re-expanded later, great care must be taken to put # quotes at appropriate points throughout the makefile. Thanks, Bill. # paths for 32-bit executables on 64-bit Windows aren't yet defined here (TODO) ifeq ($(system), Windows) pkglibdir := $(APPDATA)/Pd pdbinpath := $(wildcard $(externalsdir)/../pd/bin) pdincludepath := $(wildcard $(externalsdir)/../pd/src) ifndef pdbinpath pdbinpath := $(shell ls -d "$(PROGRAMFILES)/pd/bin") endif ifndef pdincludepath pdincludepath := $(shell ls -d "$(PROGRAMFILES)/pd/include/pdextended") endif ifndef pdincludepath pdincludepath := $(shell ls -d "$(PROGRAMFILES)/pd/src") endif endif # On Windows we build 32 bit by default to match Pd(-extended) binary # distributions. This may change in the future. # TODO: decide whether -mms-bitfields should be specified. ifeq ($(system), Windows) extension = dll CC = gcc CXX = g++ arch.c.flags := -march=pentium4 -msse -msse2 -mfpmath=sse cpp.flags := -DMSW -DNT c.flags := c.ldflags := -static-libgcc -shared \ -Wl,--enable-auto-import "$(pdbinpath)/pd.dll" c.ldlibs := cxx.flags := -fcheck-new cxx.ldflags := -static-libstdc++ -shared \ -Wl,--enable-auto-import "$(pdbinpath)/pd.dll" cxx.ldlibs := shared.extension = dll shared.ldflags := -static-libgcc -shared "$(pdbinpath)/pd.dll" stripflags = --strip-unneeded -R .note -R .comment endif #=== paths ===================================================================== # Default pkglibdir is specified above per operating system. It is aliased as # 'objectsdir' to retain compatibility with pd-extended template. Assignment # operator '?=' is used to enable a project-relative path definition in the # including makefile. objectsdir ?= $(pkglibdir) # base path where all components of the lib will be installed by default installpath := $(DESTDIR)$(objectsdir)/$(lib.name) # check if pdincludepath contains spaces (as is often the case on Windows) # if so, store the path so we can later do checks with it pdincludepathwithspaces := $(if $(word 2, $(pdincludepath)), $(pdincludepath)) #=== accumulated build flags =================================================== # From GNU make docs: 'Users expect to be able to specify CFLAGS freely # themselves.' So we use CFLAGS to define options which are not strictly # required for compilation: optimizations, architecture specifications, and # warnings. CFLAGS can be safely overriden using a make command argument. # Variables cflags, ldflags and ldlibs may be defined in including makefile. optimization.flags = -O3 -ffast-math -funroll-loops -fomit-frame-pointer warn.flags = -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing # suppress -Wunused-variable & Co if you don't want to clutter a build log ifdef suppress-wunused warn.flags += $(addprefix -Wno-unused-, function parameter value variable) endif CFLAGS = $(warn.flags) $(optimization.flags) $(arch.c.flags) # preprocessor flags cpp.flags += -DPD -I "$(pdincludepath)" $(CPPFLAGS) # architecture specifications for linker are overridable by LDFLAGS LDFLAGS := $(arch.ld.flags) # now add the same ld flags to shared dynamic lib shared.ldflags := $(shared.ldflags) $(LDFLAGS) # accumulated flags for C compiler / linker c.flags := $(cpp.flags) $(c.flags) $(cflags) $(CFLAGS) c.ldflags := $(c.ldflags) $(ldflags) $(LDFLAGS) c.ldlibs := $(c.ldlibs) $(ldlibs) # accumulated flags for C++ compiler / linker cxx.flags := $(cpp.flags) $(cxx.flags) $(cflags) $(CFLAGS) cxx.ldflags := $(cxx.ldflags) $(ldflags) $(LDFLAGS) cxx.ldlibs := $(cxx.ldlibs) $(ldlibs) ################################################################################ ### variables: tools ########################################################### ################################################################################ # aliases so we can later define 'compile-$1' and set 'c' or 'cxx' as argument compile-c := $(CC) compile-cxx := $(CXX) ################################################################################ ### checks ##################################################################### ################################################################################ # At this point most variables are defined. Now do some checks and info's # before rules begin. # 'forward declaration' of default target, needed to do checks all: # To avoid unpredictable results, make sure the default target is not redefined # by including makefile. ifneq ($(.DEFAULT_GOAL), all) $(error Default target must be 'all'.) endif # find out which target(s) will be made ifdef MAKECMDGOALS goals := $(MAKECMDGOALS) else goals := all endif # store path to Pd API m_pd.h if it is found ifdef pdincludepath mpdh := $(shell ls "$(pdincludepath)/m_pd.h") endif # print Makefile.pdlibbuilder version $(info ++++ info: using Makefile.pdlibbuilder version $(version)) # when making target all, check if m_pd.h is found and print info about it ifeq ($(goals), all) $(if $(mpdh), \ $(info ++++ info: using Pd API $(mpdh)), \ $(warning Where is Pd API m_pd.h? Do 'make help' for info.)) endif # print target info $(info ++++ info: making target $(goals) $(if $(lib.name),in lib $(lib.name))) # when installing, print installpath info $(if $(filter install install-lib, $(goals)), $(info ++++ info: \ installpath is '$(installpath)')) #=== define executables ======================================================== # By default we build class executables, and optionally a shared dynamic link # lib. When make-lib-executable=yes we build all classes into a single lib # executable, on the condition that variable lib.setup.sources is defined. ifeq ($(make-lib-executable),yes) $(if $(lib.setup.sources), ,\ $(error Can not build library blob because lib.setup.sources is undefined)) executables := $(lib.name).$(extension) else executables := $(classes.executables) $(shared.lib) endif ################################################################################ ### rules: special targets ##################################################### ################################################################################ # Disable built-in rules. If some target can't be built with the specified # rules, it should not be built at all. MAKEFLAGS += --no-builtin-rules .PRECIOUS: .SUFFIXES: .PHONY: all post build-lib \ $(classes) $(makefiledirs) $(makefiles) \ install install-executables install-datafiles install-datadirs \ force clean vars allvars depend help ################################################################################ ### rules: build targets ####################################################### ################################################################################ # Target all forces the build of targets [$(executables) post] in # deterministic order. Target $(executables) builds class executables plus # optional shared lib or alternatively a single lib executable when # make-lib-executable=true. Target post is optionally defined by # library makefile. all: post post: $(executables) all: $(info ++++info: target all in lib $(lib.name) completed) # build all with -g option turned on for debug symbols alldebug: c.flags += -g alldebug: cxx.flags += -g alldebug: all #=== class executable ========================================================== # recipe for linking objects in class executable # argument $1 = compiler type (c or cxx) # argument $2 = class basename define link-class $(compile-$1) \ $($1.ldflags) $($2.class.ldflags) \ -o $2.$(extension) \ $(addsuffix .o, $(basename $($2.class.sources))) \ $(addsuffix .o, $(basename $(common.sources))) \ $($1.ldlibs) $($2.class.ldlibs) $(shared.lib) endef # general rule for linking object files in class executable %.$(extension): $(shared.lib) $(info ++++ info: linking objects in $@ for lib $(lib.name)) $(if $(filter %.cc %.cpp, $($*.class.sources)), \ $(call link-class,cxx,$*), \ $(call link-class,c,$*)) #=== library blob ============================================================== # build all classes into single executable build-lib: $(lib.name).$(extension) $(info ++++ info: library blob $(lib.name).$(extension) completed) # recipe for linking objects in lib executable # argument $1 = compiler type (c or cxx) define link-lib $(compile-$1) \ $($1.ldflags) $(lib.ldflags) \ -o $(lib.name).$(extension) $(all.objects) \ $($1.ldlibs) $(lib.ldlibs) endef # rule for linking objects in lib executable # declared conditionally to avoid name clashes ifeq ($(make-lib-executable),yes) $(lib.name).$(extension): $(all.objects) $(if $(filter %.cc %.cpp, $(all.sources)), \ $(call link-lib,cxx), \ $(call link-lib,c)) endif #=== shared dynamic lib ======================================================== # recipe for linking objects in shared executable # argument $1 = compiler type (c or cxx) define link-shared $(compile-$1) \ $(shared.ldflags) \ -o lib$(lib.name).$(shared.extension) $(shared.objects) \ $($1.ldlibs) $(shared.ldlibs) endef # rule for linking objects in shared executable # build recipe is in macro 'link-shared' lib$(lib.name).$(shared.extension): $(shared.objects) $(info ++++ info: linking objects in shared lib $@) $(if $(filter %.cc %.cpp, $(shared.sources)), \ $(call link-shared,cxx), \ $(call link-shared,c)) #=== object files ============================================================== # recipe to make .o file from source # argument $1 is compiler type (c or cxx) define make-object-file $(info ++++ info: making $@ in lib $(lib.name)) $(compile-$1) \ $($1.flags) \ -o $@ -c $< endef # Three rules to create .o files. These are double colon 'terminal' rules, # meaning they are the last in a rules chain. %.o:: %.c $(call make-object-file,c) %.o:: %.cc $(call make-object-file,cxx) %.o:: %.cpp $(call make-object-file,cxx) #=== explicit prerequisites for class executables ============================== # For class executables, prerequisite rules are declared in run time. Target # 'depend' prints these rules for debugging purposes. # declare explicit prerequisites rule like 'class: class.extension' # argument $v is class basename define declare-class-target $v: $v.$(extension) endef # declare explicit prerequisites rule like 'class.extension: object1.o object2.o' # argument $v is class basename define declare-class-executable-target $v.$(extension): $(addsuffix .o, $(basename $($v.class.sources))) \ $(addsuffix .o, $(basename $(common.sources))) endef # evaluate explicit prerequisite rules for all classes $(foreach v, $(classes), $(eval $(declare-class-target))) $(foreach v, $(classes), $(eval $(declare-class-executable-target))) #=== implicit prerequisites for class executables ============================== # Evaluating implicit prerequisites (header files) with help from the # preprocessor is 'expensive' so this is done conditionally and selectively. # Note that it is also possible to trigger a build via install targets, in # which case implicit prerequisites are not checked. # When the Pd include path contains spaces it will mess up the implicit # prerequisites rules. Also it is known that multiple arch flags are # incompatible with preprocessor option -MM on OSX <= 10.5. Dependency # tracking must be disabled in those cases. oldfat := $(and $(filter ppc i386, $(machine)), \ $(filter-out 0 1, $(words $(filter -arch, $(c.flags))))) disable-dependency-tracking := $(strip $(pdincludepathwithspaces) $(oldfat)) ifndef disable-dependency-tracking must-build-everything := $(filter all, $(goals)) must-build-class := $(filter $(classes), $(goals)) must-build-sources := $(foreach v, $(must-build-class), $($v.class.sources)) endif # declare implicit prerequisites rule like 'object.o: header1.h header2.h ...' # argument $1 is input source file(s) # dir is explicitly added because option -MM strips it by default define declare-object-target $(dir $1)$(filter %.o: %.h, $(shell $(CPP) $(c.flags) -MM $1)) $(MAKEFILE_LIST) endef # evaluate implicit prerequisite rules when rebuilding everything ifdef must-build-everything $(if $(wildcard $(all.objects)), \ $(info ++++ info: evaluating implicit prerequisites in lib $(lib.name).....) \ $(foreach v, $(all.sources), $(eval $(call declare-object-target, $v)))) endif # evaluate implicit prerequisite rules when selectively building classes ifdef must-build-class $(foreach v, $(must-build-sources), \ $(eval $(call declare-object-target, $v))) $(foreach v, $(shared.sources), \ $(eval $(call declare-object-target, $v))) endif ################################################################################ ### rules: preprocessor and assembly files ##################################### ################################################################################ # Preprocessor and assembly output files for bug tracing etc. They are not part # of the build processes for executables. By default these files are created in # the current working directory. Dependency tracking is not performed, the build # is forced instead to make sure it's up to date. force: #=== preprocessor file ========================================================= # make preprocessor output file with extension .pre # argument $1 = compiler type (c or cxx) define make-preprocessor-file $(info ++++ info: making preprocessor output file $(notdir $*.pre) \ in current working directory) $(compile-$1) -E $< $(c.flags) $($1.flags) -o $(notdir $*.pre) endef %.pre:: %.c force $(call make-preprocessor-file,c) %.pre:: %.cc force $(call make-preprocessor-file,cxx) %.pre:: %.cpp force $(call make-preprocessor-file,cxx) #=== assembly file ============================================================= # make C / assembly interleaved output file with extension .lst # argument $1 = compiler type (c or cxx) define make-assembly-file $(info ++++ info: making assembly output file $(notdir $*.lst) \ in current working directory) $(compile-$1) \ -c -Wa,-a,-ad -fverbose-asm \ $($1.flags) \ $< > $(notdir $*.lst) endef %.lst:: %.c force $(call make-assembly-file,c) %.lst:: %.cc force $(call make-assembly-file,cxx) %.lst:: %.cpp force $(call make-assembly-file,cxx) ################################################################################ ### rules: installation targets ################################################ ################################################################################ # Install targets depend on successful exit status of target all because nothing # must be installed in case of a build error. # -p = preserve time stamps # -m = set permission mode (as in chmod) # -d = create all components of specified directories INSTALL = install INSTALL_PROGRAM := $(INSTALL) -p -m 644 INSTALL_DATA := $(INSTALL) -p -m 644 INSTALL_DIR := $(INSTALL) -m 755 -d # strip spaces from file names executables := $(strip $(executables)) datafiles := $(strip $(datafiles)) datadirs := $(strip $(datadirs)) # Do not make any install sub-target with empty variable definition because the # install program would exit with an error. install: $(if $(executables), install-executables) install: $(if $(datafiles), install-datafiles) install: $(if $(datadirs), install-datadirs) install-executables: all $(INSTALL_DIR) -v "$(installpath)" $(INSTALL_PROGRAM) $(executables) "$(installpath)" $(info ++++ info: executables of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) install-datafiles: all $(INSTALL_DIR) -v "$(installpath)" $(INSTALL_DATA) $(datafiles) "$(installpath)" $(info ++++ info: data files of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) install-datadirs: all $(foreach v, $(datadirs), $(INSTALL_DIR) "$(installpath)/$v";) $(foreach v, $(datadirs), \ $(INSTALL_DATA) $(wildcard $v/*) "$(installpath)/$v";) $(info ++++ info: data directories of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) ################################################################################ ### rules: distribution targets ################################################ ################################################################################ # TODO # These targets are implemented in Makefile Template, but I have to figure out # how to do it under the not-so-strict conditions of Makefile.pdlibbuilder. # make source package dist: @echo "target dist not yet implemented" # make Debian source package dpkg-source: @echo "target dpkg-source not yet implemented" $(ORIGDIR): $(DISTDIR): ################################################################################ ### rules: clean targets ####################################################### ################################################################################ # delete build products from build tree clean: rm -f $(all.objects) rm -f $(classes.executables) $(lib.name).$(extension) $(shared.lib) rm -f *.pre *.lst # remove distribution directories and tarballs from build tree distclean: clean @echo "target distclean not yet implemented" ################################################################################ ### rules: submake targets ##################################################### ################################################################################ # Iterate over sub-makefiles or makefiles in other directories. # When 'continue-make=yes' is set, sub-makes will report 'true' to the parent # process regardless of their real exit status. This prevents the parent make # from being aborted by a sub-make error. Useful when you want to quickly find # out which sub-makes from a large set will succeed. ifeq ($(continue-make),yes) continue = || true endif # These targets will trigger sub-make processes for entries in 'makefiledirs' # and 'makefiles'. all alldebug install clean distclean dist dkpg-source: \ $(makefiledirs) $(makefiles) # this expands to identical rules for each entry in 'makefiledirs' $(makefiledirs): $(MAKE) --directory=$@ $(MAKECMDGOALS) $(continue) # this expands to identical rules for each entry in 'makefiles' $(makefiles): $(MAKE) --directory=$(dir $@) --makefile=$(notdir $@) $(MAKECMDGOALS) $(continue) ################################################################################ ### rules: convenience targets ################################################# ################################################################################ #=== show variables ============================================================ # Several 'function' macro's cause errors when expanded within a rule or without # proper arguments. Variables which are set with the define directive are only # shown by name for that reason. functions = \ add-class-source \ declare-class-target \ declare-class-executable-target \ declare-object-target \ link-class \ link-lib \ link-shared \ make-object-file \ make-preprocessor-file \ make-assembly-file # show variables from makefiles vars: $(info ++++ info: showing makefile variables:) $(foreach v,\ $(sort $(filter-out $(functions) functions, $(.VARIABLES))),\ $(if $(filter file, $(origin $v)),\ $(info variable $v = $($v)))) $(foreach v, $(functions), $(info 'function' name: $v)) @echo # show all variables allvars: $(info ++++ info: showing default, automatic and makefile variables:) $(foreach v, \ $(sort $(filter-out $(functions) functions, $(.VARIABLES))), \ $(info variable ($(origin $v)) $v = $($v))) $(foreach v, $(functions), $(info 'function' name: $v)) @echo #=== show dependencies ========================================================= # show generated prerequisites rules depend: $(info ++++ info: generated prerequisite rules) $(foreach v, $(classes), $(info $(declare-class-target))) $(foreach v, $(classes), $(info $(declare-class-executable-target))) $(foreach v, $(all.sources), $(info $(call declare-object-target, $v))) @echo #=== show help text ============================================================ # brief info about targets and paths ifdef mpdh mpdhinfo := $(mpdh) else mpdhinfo := m_pd.h was not found. Is Pd(-extended) installed? endif help: @echo @echo " Main targets:" @echo " all: build executables (default target)" @echo " install: install all components of the library" @echo " vars: print makefile variables for troubleshooting" @echo " allvars: print all variables for troubleshooting" @echo " help: print this help text" @echo @echo " Pd API m_pd.h:" @echo " $(mpdhinfo)" @echo " You may specify your preferred Pd include path as argument to" @echo " the make command, like 'pdincludepath=path/to/pd/src'." @echo @echo " Path for installation of your libdir(s):" @echo " $(objectsdir)" @echo " Alternatively you may specify your path for installation as argument" @echo " to the make command, like 'objectsdir=path/to/pd-externals'." @echo @echo " Default paths are listed in the doc sections in Makefile.pdlibbuilder." @echo #=== dummy target ============================================================== coffee: @echo "Makefile.pdlibbuilder: Can not make coffee. Sorry." ################################################################################ ### end of rules sections ###################################################### ################################################################################ # for syntax highlighting in vim and github # vim: set filetype=make: pd-miXedSon-0.2beta3/README.md000066400000000000000000000047161276723360300157210ustar00rootroot00000000000000This is a forked version of https://svn.code.sf.net/p/pure-data/svn/trunk/externals/miXed/cyclone. For active development see https://github.com/porres/pd-cyclone. The local repository is in 'maintainance' only mode.
pd-cyclone is a 'fork' of https://svn.code.sf.net/p/pure-data/svn/trunk/externals/miXed/cyclone (via the https://git.puredata.info/cgit/svn2git/libraries/miXed.git/ migrated repository). It is cleaned to contain only the cyclone functionality. Other parts of the miXed library are either moved (pddp) or unmaintained (toxy, ViCious, riddle). Cyclone and miXed is written by Krzysztof Czaja. A copy of the original cyclone page is available here: http://fjkraan.home.xs4all.nl/digaud/puredata/cyclone/cyclone_site/cyclone.html Within the cyclone file set, the transition to a new build system, started with 0.1-alpha57 is completed. The initial version at this github repository will be 0.2beta1. The new build system is pd-lib-builder based and only builds each object in a separate file. The old build configuration also compiled to the hammer and sickle library objects and included a cyclone meta-library. The original location of this repository is https://github.com/electrickery/pd-cyclone. Goals The original goal of cyclone was to create a collection of Max/MSP objects for PureData. This was in the 2000s area, Max/MSP version 4.6. Since then MAX evolved its architecture and file format to something that is incompatible with PureData. Compatibility in patch file level is limited to this very old version of Max/MSP. Since then an unknown number of patches is made for these objects in Pure Data. This leads to an additional goal of keeping the functionality backward compatible. Only bug fixes, new objects and if possible, different behaviour with extra arguments or messages will be added. Objects that are incompatible with current Cyclone should have another name or be placed in other libraries. Compiling with pdlibbuilder PdLibBuilder tries to find the Pd source directory at several common locations, but when this fails, yo have to specify the path yourself using the pdincludepath variable. Example:
make pdincludepath=~/pd-0.46-6/src/  (for Windows/MinGW add 'pdbinpath=~/pd-0.46-6/bin/)
Installing with pdlibbuilder The default path for installing might not be the best, surely for testing. Use the pkglibdir variable for this. Example:
make install pkglibdir=~/pd-externals/
pd-miXedSon-0.2beta3/build_counter000066400000000000000000000001771276723360300172200ustar00rootroot00000000000000#define CYCLONE_VERSION "0.2" #define CYCLONE_RELEASE "beta" #define CYCLONE_BUILD 3 #if 0 CYCLONE_SNAPSHOT = 0.2beta3 #endif pd-miXedSon-0.2beta3/cyclone-meta.pd000066400000000000000000000014461276723360300173440ustar00rootroot00000000000000#N canvas 387 545 450 350 10; #X text 16 34 LICENSE SIBSD; #X text 16 142 LIBRARY cyclone; #X text 16 124 OUTLET_0 signal; #X text 16 70 INLET_0 signal message; #X text 16 16 KEYWORDS signal wavetable wave table interpolation; #X text 16 52 DESCRIPTION variable size wavetable; #X text 16 88 INLET_1 float signal; #X text 16 106 INLET_2 float signal; #X text 15 160 VERSION 0.2-beta3; #X text 15 178 AUTHOR Krzysztof Czaja; #X text 16 196 RELEASE_DATE 2002; #X text 17 215 WEBSITE http://suita.chopin.edu.pl/~czaja/miXed/externs/cyclone.html ; #X text 17 247 HELP_PATCH_AUTHORS Christoph Kummerer. Revised by Jonathan Wilkes for Pd-extended 0.42 to conform to the PDDP template. Alex Cleveland updated this patch for Pd-l2ork version 2013.05.28. Fred Jan Kraan adapted the patch to pd-extended 2014-12-03; pd-miXedSon-0.2beta3/hammer/000077500000000000000000000000001276723360300157035ustar00rootroot00000000000000pd-miXedSon-0.2beta3/hammer/Append.c000066400000000000000000000213331276723360300172600ustar00rootroot00000000000000/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include "m_pd.h" #include "common/loud.h" #include "common/grow.h" #include "common/fitter.h" #define APPEND_INISIZE 32 /* LATER rethink */ #define APPEND_MAXSIZE 256 typedef struct _append { t_object x_ob; int x_size; /* as allocated */ int x_natoms; /* as used */ t_atom *x_message; t_atom *x_messbuf; t_atom x_messini[APPEND_INISIZE]; int x_entered; int x_auxsize; t_atom *x_auxbuf; t_pd *x_proxy; } t_append; typedef struct _appendxy { t_pd xy_pd; t_append *xy_owner; } t_appendxy; static t_class *append_class; static t_class *appendxy_class; static int append_iscompatible = 0; /* FIXME per-object */ /* Usually a preallocation method is used, except in special cases of: 1) reentrant output request, or 2) an output request which would cause resizing to more than MAXSIZE (no such limit for a 'set' message). In both special cases, a temporary output buffer is allocated. A separately preallocated output buffer is not used, thus avoiding memcpying of the stored message (a small performance gain when the preallocation method is chosen). Instead, self-invoked 'set' messages are postponed, using an auxiliary buffer. */ /* Any Append's output, except bangout, goes through outlet_anything() -> typedmess(), LATER rethink */ static void append_setnatoms(t_append *x, int natoms) { x->x_message = x->x_messbuf + x->x_size - natoms; x->x_natoms = natoms; } static void append_bangout(t_outlet *outp, int ac, t_atom *av) { if (ac) { if (av->a_type == A_SYMBOL) outlet_anything(outp, av->a_w.w_symbol, ac-1, av+1); else if (av->a_type == A_POINTER) { if (ac == 1) outlet_pointer(outp, av->a_w.w_gpointer); else outlet_list(outp, &s_list, ac, av); } else if (av->a_type == A_FLOAT) { if (ac == 1) outlet_float(outp, av->a_w.w_float); else outlet_list(outp, &s_list, ac, av); } else loudbug_bug("append_bangout"); } else outlet_bang(outp); } static void append_anything(t_append *x, t_symbol *s, int ac, t_atom *av) { int reentered = x->x_entered; int prealloc = !reentered; int ntotal = x->x_natoms + ac; t_atom *buf; x->x_entered = 1; if (prealloc && ntotal > x->x_size) { if (ntotal > APPEND_MAXSIZE) prealloc = 0; else { int nrequested = ntotal; x->x_messbuf = grow_withtail(&nrequested, &x->x_natoms, (char **)&x->x_message, &x->x_size, x->x_messbuf, APPEND_INISIZE, x->x_messini, sizeof(*x->x_message)); prealloc = (nrequested == ntotal); } } if (prealloc) { buf = x->x_message - ac; if (ac) memcpy(buf, av, ac * sizeof(*buf)); if (s) outlet_anything(((t_object *)x)->ob_outlet, s, ntotal, buf); else append_bangout(((t_object *)x)->ob_outlet, ntotal, buf); } else { /* LATER consider using the stack if ntotal <= MAXSTACK */ if (buf = getbytes(ntotal * sizeof(*buf))) { if (ac) memcpy(buf, av, ac * sizeof(*buf)); if (x->x_natoms) memcpy(buf + ac, x->x_message, x->x_natoms * sizeof(*buf)); if (s) outlet_anything(((t_object *)x)->ob_outlet, s, ntotal, buf); else append_bangout(((t_object *)x)->ob_outlet, ntotal, buf); freebytes(buf, ntotal * sizeof(*buf)); } } if (!reentered) { x->x_entered = 0; if (x->x_auxbuf) { if (x->x_auxsize <= x->x_size) { append_setnatoms(x, x->x_auxsize / 2); memcpy(x->x_message, x->x_auxbuf + x->x_natoms, x->x_natoms * sizeof(*x->x_message)); freebytes(x->x_auxbuf, x->x_auxsize * sizeof(*x->x_auxbuf)); } else { if (x->x_messbuf != x->x_messini) freebytes(x->x_messbuf, x->x_size * sizeof(*x->x_messbuf)); x->x_size = x->x_auxsize; x->x_messbuf = x->x_auxbuf; append_setnatoms(x, x->x_auxsize / 2); } x->x_auxbuf = 0; } } } static void append_bang(t_append *x) { if (append_iscompatible) { /* CHECKED: a nop */ } else append_anything(x, 0, 0, 0); } static void append_float(t_append *x, t_float f) { t_atom at; SETFLOAT(&at, f); append_anything(x, &s_list, 1, &at); /* CHECKED: converted to list */ } /* CHECKED: incompatible -- LATER consider converting to anything */ static void append_symbol(t_append *x, t_symbol *s) { t_atom at; SETSYMBOL(&at, s); append_anything(x, &s_symbol, 1, &at); } /* LATER gpointer */ static void append_doset(t_append *x, t_symbol *s, int ac, t_atom *av) { int newsize = ac * 2; if (s) newsize += 2; if (newsize > 0) { if (x->x_entered) { if (x->x_auxbuf) { loud_warning((t_pd *)x, 0, "\'set\' message overridden"); freebytes(x->x_auxbuf, x->x_auxsize * sizeof(*x->x_auxbuf)); x->x_auxsize = 0; } if (x->x_auxbuf = getbytes(newsize * sizeof(*x->x_auxbuf))) { t_atom *ap = x->x_auxbuf + ac; if (s) { ap++; SETSYMBOL(ap, s); ap++; } if (ac) memcpy(ap, av, ac * sizeof(*x->x_auxbuf)); x->x_auxsize = newsize; } } else { t_atom *ap; if (newsize > x->x_size) { int sz = newsize; x->x_messbuf = grow_nodata(&sz, &x->x_size, x->x_messbuf, APPEND_INISIZE, x->x_messini, sizeof(*x->x_messbuf)); if (sz != newsize) { ac = sz / 2; /* LATER rethink */ if (s) ac--; } } if (s) { append_setnatoms(x, ac + 1); ap = x->x_message; SETSYMBOL(ap, s); ap++; } else { append_setnatoms(x, ac); ap = x->x_message; } while (ac--) *ap++ = *av++; } } } static void append_set(t_append *x, t_symbol *s, int ac, t_atom *av) { if (x->x_proxy) append_anything(x, s, ac, av); else /* LATER (when?) controlled by maxmode */ append_doset(x, 0, ac, av); } static void appendxy_bang(t_appendxy *xy) { append_doset(xy->xy_owner, 0, 0, 0); /* LATER rethink */ } static void appendxy_float(t_appendxy *xy, t_float f) { t_atom at; SETFLOAT(&at, f); append_doset(xy->xy_owner, 0, 1, &at); } static void appendxy_symbol(t_appendxy *xy, t_symbol *s) { t_atom at; if (!s || s == &s_) s = &s_symbol; /* LATER rethink */ SETSYMBOL(&at, s); append_doset(xy->xy_owner, 0, 1, &at); } static void appendxy_list(t_appendxy *xy, t_symbol *s, int ac, t_atom *av) { if (ac) append_doset(xy->xy_owner, 0, ac, av); else { /* LATER rethink */ t_atom at; SETSYMBOL(&at, &s_list); append_doset(xy->xy_owner, 0, 1, &at); } } static void appendxy_anything(t_appendxy *xy, t_symbol *s, int ac, t_atom *av) { append_doset(xy->xy_owner, s, ac, av); } static void append_free(t_append *x) { if (x->x_messbuf != x->x_messini) freebytes(x->x_messbuf, x->x_size * sizeof(*x->x_messbuf)); if (x->x_auxbuf) { loudbug_bug("append_free"); /* LATER rethink */ freebytes(x->x_auxbuf, x->x_auxsize * sizeof(*x->x_auxbuf)); } if (x->x_proxy) pd_free(x->x_proxy); } static void *append_new(t_symbol *s, int ac, t_atom *av) { t_append *x = (t_append *)pd_new(append_class); x->x_size = APPEND_INISIZE; x->x_natoms = 0; x->x_messbuf = x->x_messini; x->x_auxbuf = 0; x->x_entered = 0; append_setnatoms(x, 0); if (ac) { x->x_proxy = 0; append_doset(x, 0, ac, av); } else { x->x_proxy = pd_new(appendxy_class); ((t_appendxy *)x->x_proxy)->xy_owner = x; inlet_new((t_object *)x, x->x_proxy, 0, 0); } outlet_new((t_object *)x, &s_anything); return (x); } static void append_fitter(void) { append_iscompatible = fittermax_get(); } void Append_setup(void) { append_class = class_new(gensym("Append"), (t_newmethod)append_new, (t_method)append_free, sizeof(t_append), 0, A_GIMME, 0); class_addbang(append_class, append_bang); class_addfloat(append_class, append_float); class_addsymbol(append_class, append_symbol); class_addlist(append_class, append_anything); /* LATER rethink */ class_addanything(append_class, append_anything); class_addmethod(append_class, (t_method)append_set, gensym("set"), A_GIMME, 0); appendxy_class = class_new(gensym("append"), 0, 0, sizeof(t_appendxy), CLASS_PD | CLASS_NOINLET, 0); class_addbang(appendxy_class, appendxy_bang); class_addfloat(appendxy_class, appendxy_float); class_addsymbol(appendxy_class, appendxy_symbol); class_addlist(appendxy_class, appendxy_list); class_addanything(appendxy_class, appendxy_anything); fitter_setup(append_class, append_fitter); } void append_setup(void) { Append_setup(); } pd-miXedSon-0.2beta3/hammer/Borax.c000066400000000000000000000124021276723360300171210ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* The first version of this code was written by Olaf Matthes. It was entirely reimplemented in the hope of adapting it to the cyclone's guidelines. */ #include #include "m_pd.h" #include "common/loud.h" #define BORAX_MAXVOICES 128 /* CHECKME */ typedef struct _Borax_voice { int v_index; /* free iff zero */ double v_onset; int v_nonsets; } t_Borax_voice; typedef struct _Borax { t_object x_ob; int x_vel; /* CHECKME t_float controlled with floatinlet (CHECKME the same in flush) */ double x_onset; int x_nonsets; int x_ndurs; int x_ndtimes; int x_minindex; int x_indices[BORAX_MAXVOICES]; /* 0 (free) or 1 (used) */ int x_nvoices; t_Borax_voice x_voices[BORAX_MAXVOICES]; t_outlet *x_voiceout; t_outlet *x_nvoicesout; t_outlet *x_pitchout; t_outlet *x_velout; t_outlet *x_ndursout; t_outlet *x_durout; t_outlet *x_ndtimesout; t_outlet *x_dtimeout; } t_Borax; static t_class *Borax_class; static void Borax_delta(t_Borax *x) { /* CHECKME first note */ float dtime = clock_gettimesince(x->x_onset); /* CHECKME */ outlet_float(x->x_dtimeout, dtime); outlet_float(x->x_ndtimesout, ++x->x_ndtimes); /* CHECKME */ } static void Borax_durout(t_Borax *x, int pitch) { float dur = clock_gettimesince(x->x_voices[pitch].v_onset); /* CHECKME */ outlet_float(x->x_durout, dur); outlet_float(x->x_ndursout, ++x->x_ndurs); /* CHECKME */ } static void Borax_float(t_Borax *x, t_float f) { int pitch; if (loud_checkint((t_pd *)x, f, &pitch, &s_float)) /* CHECKME */ { int index; if (pitch < 0 || pitch >= BORAX_MAXVOICES) { /* CHECKME pitch range, complaints */ return; } index = x->x_voices[pitch].v_index; if (x->x_vel) { if (index) return; /* CHECKME */ x->x_indices[index = x->x_minindex] = 1; while (x->x_indices[++x->x_minindex]); index++; /* CHECKME one-based? */ Borax_delta(x); x->x_onset = clock_getlogicaltime(); /* CHECKME (in delta?) */ x->x_voices[pitch].v_index = index; x->x_voices[pitch].v_onset = x->x_onset; x->x_voices[pitch].v_nonsets = ++x->x_nonsets; x->x_nvoices++; } else { if (!index) return; /* CHECKME */ index--; x->x_indices[index] = 0; if (index < x->x_minindex) x->x_minindex = index; index++; Borax_durout(x, pitch); x->x_voices[pitch].v_index = 0; x->x_nvoices--; } outlet_float(x->x_velout, x->x_vel); outlet_float(x->x_pitchout, pitch); outlet_float(x->x_nvoicesout, x->x_nvoices); outlet_float(x->x_voiceout, index); outlet_float(((t_object *)x)->ob_outlet, x->x_voices[pitch].v_nonsets); } } static void Borax_ft1(t_Borax *x, t_floatarg f) { x->x_vel = (int)f; /* CHECKME */ } static void Borax_reset(t_Borax *x) { x->x_vel = 0; x->x_onset = clock_getlogicaltime(); x->x_nonsets = x->x_ndurs = x->x_ndtimes = 0; x->x_minindex = 0; memset(x->x_indices, 0, sizeof(x->x_indices)); x->x_nvoices = 0; memset(x->x_voices, 0, sizeof(x->x_voices)); } static void Borax_bang2(t_Borax *x) { int pitch; for (pitch = 0; pitch < BORAX_MAXVOICES; pitch++) { if (x->x_voices[pitch].v_index) { /* CHECKME counters, etc. */ Borax_durout(x, pitch); outlet_float(x->x_velout, 0); outlet_float(x->x_pitchout, pitch); outlet_float(x->x_nvoicesout, --x->x_nvoices); outlet_float(x->x_voiceout, x->x_voices[pitch].v_index); outlet_float(((t_object *)x)->ob_outlet, x->x_voices[pitch].v_nonsets); } } Borax_reset(x); } /* CHECKME flush in a destructor */ static void *Borax_new(void) { t_Borax *x = (t_Borax *)pd_new(Borax_class); inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); inlet_new((t_object *)x, (t_pd *)x, &s_bang, gensym("bang2")); outlet_new((t_object *)x, &s_float); x->x_voiceout = outlet_new((t_object *)x, &s_float); x->x_nvoicesout = outlet_new((t_object *)x, &s_float); x->x_pitchout = outlet_new((t_object *)x, &s_float); x->x_velout = outlet_new((t_object *)x, &s_float); x->x_ndursout = outlet_new((t_object *)x, &s_float); x->x_durout = outlet_new((t_object *)x, &s_float); x->x_ndtimesout = outlet_new((t_object *)x, &s_float); x->x_dtimeout = outlet_new((t_object *)x, &s_float); Borax_reset(x); return (x); } void Borax_setup(void) { Borax_class = class_new(gensym("Borax"), (t_newmethod)Borax_new, 0, sizeof(t_Borax), 0, 0); class_addcreator((t_newmethod)Borax_new, gensym("borax"), 0, 0); class_addcreator((t_newmethod)Borax_new, gensym("cyclone/borax"), 0, 0); class_addfloat(Borax_class, Borax_float); /* CHECKME list unfolding */ class_addmethod(Borax_class, (t_method)Borax_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(Borax_class, (t_method)Borax_bang2, gensym("bang2"), 0); class_addmethod(Borax_class, (t_method)Borax_delta, gensym("delta"), 0); } void borax_setup(void) { Borax_setup(); } pd-miXedSon-0.2beta3/hammer/Bucket.c000066400000000000000000000101701276723360300172630ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* This is a modified version of Joseph A. Sarlo's code. The most important changes are listed in "pd-lib-notes.txt" file. */ #include "m_pd.h" #include "shared.h" typedef struct _Bucket { t_object x_ob; int x_numbucks; t_float *x_bucks; /* CHECKED: no limit */ t_outlet **x_outs; short int x_frozen; /* 0 for thawed, 1 for frozen */ short int x_dir; /* 0 for L2R, 1 for R2L */ short int x_max5mode; /* 0 for classic Max 4.6 mode, 1 for Max 5 mode (with 2nd !0 argument) */ } t_Bucket; static t_class *Bucket_class; static void Bucket_bang(t_Bucket *x) { int i = x->x_numbucks; /* CHECKED: outlets output in right-to-left order */ while (i--) outlet_float(x->x_outs[i], x->x_bucks[i]); } static void Bucket_float(t_Bucket *x, t_float val) { int i; if (!x->x_frozen) Bucket_bang(x); if (!x->x_dir) { for (i = x->x_numbucks - 1; i > 0; i--) x->x_bucks[i] = x->x_bucks[i - 1]; x->x_bucks[0] = val; } else { for (i = 0; i < x->x_numbucks - 1; i++) x->x_bucks[i] = x->x_bucks[i + 1]; x->x_bucks[x->x_numbucks - 1] = val; } if (x->x_max5mode && !x->x_frozen) Bucket_bang(x); } static void Bucket_freeze(t_Bucket *x) { x->x_frozen = 1; } static void Bucket_thaw(t_Bucket *x) { x->x_frozen = 0; } static void Bucket_roll(t_Bucket *x) { if (x->x_dir) Bucket_float(x, x->x_bucks[0]); else Bucket_float(x, x->x_bucks[x->x_numbucks - 1]); } static void Bucket_rtol(t_Bucket *x) { x->x_dir = 1; } static void Bucket_ltor(t_Bucket *x) { x->x_dir = 0; } static void Bucket_set(t_Bucket *x, t_floatarg f) { int i = x->x_numbucks; while (i--) x->x_bucks[i] = f; if (!x->x_frozen) /* CHECKED */ Bucket_bang(x); } static void Bucket_free(t_Bucket *x) { if (x->x_bucks) freebytes(x->x_bucks, x->x_numbucks * sizeof(*x->x_bucks)); if (x->x_outs) freebytes(x->x_outs, x->x_numbucks * sizeof(*x->x_outs)); } static void *Bucket_new(t_floatarg val, t_floatarg max5mode) { t_Bucket *x; int nbucks = (int)val; t_float *bucks; t_outlet **outs; if (nbucks < 1) nbucks = 1; if (!(bucks = (t_float *)getbytes(nbucks * sizeof(*bucks)))) return (0); if (!(outs = (t_outlet **)getbytes(nbucks * sizeof(*outs)))) { freebytes(bucks, nbucks * sizeof(*bucks)); return (0); } x = (t_Bucket *)pd_new(Bucket_class); x->x_numbucks = nbucks; x->x_bucks = bucks; x->x_outs = outs; x->x_frozen = 0; x->x_dir = 0; x->x_max5mode = ((int)max5mode != 0); while (nbucks--) *outs++ = outlet_new((t_object *)x, &s_float); return (x); } void Bucket_setup(void) { Bucket_class = class_new(gensym("Bucket"), (t_newmethod)Bucket_new, (t_method)Bucket_free, sizeof(t_Bucket), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addcreator((t_newmethod)Bucket_new, gensym("bucket"), A_DEFFLOAT, 0); class_addcreator((t_newmethod)Bucket_new, gensym("cyclone/bucket"), A_DEFFLOAT, 0); class_addbang(Bucket_class, Bucket_bang); class_addfloat(Bucket_class, Bucket_float); class_addmethod(Bucket_class, (t_method)Bucket_freeze, gensym("freeze"), 0); class_addmethod(Bucket_class, (t_method)Bucket_thaw, gensym("thaw"), 0); class_addmethod(Bucket_class, (t_method)Bucket_ltor, gensym("L2R"), 0); class_addmethod(Bucket_class, (t_method)Bucket_rtol, gensym("R2L"), 0); /* CHECKED (refman error) roll has no argument */ class_addmethod(Bucket_class, (t_method)Bucket_roll, gensym("roll"), 0); /* 3.5 additions */ class_addmethod(Bucket_class, (t_method)Bucket_set, gensym("set"), A_FLOAT, 0); class_addmethod(Bucket_class, (t_method)Bucket_ltor, gensym("l2r"), 0); class_addmethod(Bucket_class, (t_method)Bucket_rtol, gensym("r2l"), 0); // logpost(NULL, 4, "this is cyclone/Bucket %s, %dth %s build", // CYCLONE_VERSION, CYCLONE_BUILD, CYCLONE_RELEASE); } void bucket_setup(void) { Bucket_setup(); } pd-miXedSon-0.2beta3/hammer/Clip.c000066400000000000000000000073651276723360300167510ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include "m_pd.h" #include "common/grow.h" #define CLIP_INISIZE 32 /* LATER rethink */ #define CLIP_MAXSIZE 256 typedef struct _clip { t_object x_ob; float x_f1; float x_f2; int x_size; /* as allocated */ t_atom *x_message; t_atom x_messini[CLIP_INISIZE]; int x_entered; } t_clip; static t_class *clip_class; /* CHECKED case of f1 > f2: x <= f2 => f1, x > f2 => f2 (Pd implementation of clip has it the other way around) */ static void clip_float(t_clip *x, t_float f) { outlet_float(((t_object *)x)->ob_outlet, (f > x->x_f2 ? x->x_f2 : (f < x->x_f1 ? x->x_f1 : f))); } static void clip_list(t_clip *x, t_symbol *s, int ac, t_atom *av) { if (ac) { int docopy = 0; int i; t_atom *ap; t_float f1 = x->x_f1; t_float f2 = x->x_f2; for (i = 0, ap = av; i < ac; i++, ap++) { t_float f; if (ap->a_type == A_FLOAT) f = ap->a_w.w_float; else { docopy = 1; /* CHECKED: symbols inside lists are converted to zeros */ f = 0; } if (f < f1 || f > f2) docopy = 1; } if (docopy) { t_atom *buf; t_atom *bp; int reentered = x->x_entered; int prealloc = !reentered; x->x_entered = 1; if (prealloc && ac > x->x_size) { if (ac > CLIP_MAXSIZE) prealloc = 0; else x->x_message = grow_nodata(&ac, &x->x_size, x->x_message, CLIP_INISIZE, x->x_messini, sizeof(*x->x_message)); } if (prealloc) buf = x->x_message; else /* LATER consider using the stack if ntotal <= MAXSTACK */ buf = getbytes(ac * sizeof(*buf)); if (buf) { for (i = 0, ap = av, bp = buf; i < ac; i++, ap++, bp++) { t_float f = (ap->a_type == A_FLOAT ? ap->a_w.w_float : 0); if (f < f1) f = f1; else if (f > f2) f = f2; SETFLOAT(bp, f); } outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, buf); if (buf != x->x_message) freebytes(buf, ac * sizeof(*buf)); } if (!reentered) { x->x_entered = 0; } } else outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, av); } } static void clip_set(t_clip *x, t_symbol *s, int ac, t_atom *av) { x->x_f1 = 0; x->x_f2 = 0; if (ac) /* CHECKED: 'set' without arguments sets both values to 0 */ { if (av->a_type == A_FLOAT) /* CHECKED: symbol is converted to 0 */ x->x_f1 = av->a_w.w_float; av++; if (--ac) { if (av->a_type == A_FLOAT) x->x_f2 = av->a_w.w_float; } else x->x_f2 = x->x_f1; /* CHECKED */ } } static void clip_free(t_clip *x) { if (x->x_message != x->x_messini) freebytes(x->x_message, x->x_size * sizeof(*x->x_message)); } static void *clip_new(t_symbol *s, int ac, t_atom *av) { t_clip *x = (t_clip *)pd_new(clip_class); x->x_f1 = 0; x->x_f2 = 0; x->x_size = CLIP_INISIZE; x->x_message = x->x_messini; x->x_entered = 0; floatinlet_new((t_object *)x, &x->x_f1); floatinlet_new((t_object *)x, &x->x_f2); outlet_new(&x->x_ob, &s_anything); clip_set(x, 0, ac, av); return (x); } void Clip_setup(void) { clip_class = class_new(gensym("Clip"), (t_newmethod)clip_new, (t_method)clip_free, sizeof(t_clip), 0, A_GIMME, 0); class_addcreator((t_newmethod)clip_new, gensym("clip"), A_GIMME, 0); class_addcreator((t_newmethod)clip_new, gensym("cyclone/clip"), A_GIMME, 0); class_addfloat(clip_class, clip_float); class_addlist(clip_class, clip_list); class_addmethod(clip_class, (t_method)clip_set, gensym("set"), A_GIMME, 0); } void clip_setup(void) { Clip_setup(); } pd-miXedSon-0.2beta3/hammer/Decode.c000066400000000000000000000064201276723360300172340ustar00rootroot00000000000000/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* This is an entirely rewritten version of Joseph A. Sarlo's code. The most important changes are listed in "pd-lib-notes.txt" file. */ #include "m_pd.h" #include "common/loud.h" #include "common/fitter.h" #define DECODE_C74MAXOUTS 8 /* CHECKED (does it make any sense?) */ #define DECODE_DEFOUTS 1 typedef struct _Decode { t_object x_ob; int x_numouts; int x_onout; int x_allon; /* submaster switch */ int x_alloff; /* master switch */ t_outlet **x_outs; t_outlet *x_outbuf[DECODE_C74MAXOUTS]; } t_Decode; static t_class *Decode_class; /* CHECKED: all outlets deliver after any action */ /* CHECKED: outlets output in right-to-left order */ static void Decode_deliver(t_Decode *x) { int i = x->x_numouts; if (x->x_alloff) while (i--) outlet_float(x->x_outs[i], 0); else if (x->x_allon) while (i--) outlet_float(x->x_outs[i], 1); else while (i--) outlet_float(x->x_outs[i], (i == x->x_onout ? 1 : 0)); } static void Decode_float(t_Decode *x, t_floatarg f) { int val = (int)f; /* CHECKED: out-of-range input is clipped, not ignored */ if (val < 0) val = 0; else if (val >= x->x_numouts) val = x->x_numouts - 1; /* CHECKED: while in all-off mode, input is stored, not ignored */ x->x_onout = val; Decode_deliver(x); } static void Decode_allon(t_Decode *x, t_floatarg f) { x->x_allon = (f != 0); Decode_deliver(x); } static void Decode_alloff(t_Decode *x, t_floatarg f) { x->x_alloff = (f != 0); Decode_deliver(x); } static void Decode_free(t_Decode *x) { if (x->x_outs != x->x_outbuf) freebytes(x->x_outs, x->x_numouts * sizeof(*x->x_outs)); } static void *Decode_new(t_floatarg val) { t_Decode *x; int i, nouts = (int)val; t_outlet **outs; if (nouts < 1) nouts = DECODE_DEFOUTS; if (nouts > DECODE_C74MAXOUTS) { fittermax_rangewarning(Decode_class, DECODE_C74MAXOUTS, "outlets"); if (!(outs = (t_outlet **)getbytes(nouts * sizeof(*outs)))) return (0); } else outs = 0; x = (t_Decode *)pd_new(Decode_class); x->x_numouts = nouts; x->x_outs = (outs ? outs : x->x_outbuf); x->x_onout = 0; x->x_allon = 0; x->x_alloff = 0; inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft2")); for (i = 0; i < nouts; i++) x->x_outs[i] = outlet_new((t_object *)x, &s_float); return (x); } void Decode_setup(void) { Decode_class = class_new(gensym("Decode"), (t_newmethod)Decode_new, (t_method)Decode_free, sizeof(t_Decode), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)Decode_new, gensym("decode"), A_DEFFLOAT, 0); class_addcreator((t_newmethod)Decode_new, gensym("cyclone/decode"), A_DEFFLOAT, 0); class_addfloat(Decode_class, Decode_float); class_addmethod(Decode_class, (t_method)Decode_allon, gensym("ft1"), A_FLOAT, 0); class_addmethod(Decode_class, (t_method)Decode_alloff, gensym("ft2"), A_FLOAT, 0); fitter_setup(Decode_class, 0); } void decode_setup(void) { Decode_setup(); } pd-miXedSon-0.2beta3/hammer/Histo.c000066400000000000000000000054431276723360300171430ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* This is an entirely rewritten version of Joseph A. Sarlo's code. The most important changes are listed in "pd-lib-notes.txt" file. */ #include "m_pd.h" #include "common/loud.h" #define HISTO_DEFSIZE 128 typedef struct _Histo { t_object x_ob; int x_size; unsigned *x_hist; /* LATER consider using 64 bits */ int x_lastinput; t_outlet *x_countout; } t_Histo; static t_class *Histo_class; static void Histo_clear(t_Histo *x) { int i = x->x_size; while (i--) x->x_hist[i] = 0; /* CHECKED: last input is kept */ } static void Histo_doit(t_Histo *x, int val, int doincr) { if (val >= 0 && val < x->x_size) { if (doincr) { /* CHECKED: only in-range numbers are stored */ x->x_lastinput = val; x->x_hist[val]++; } outlet_float(x->x_countout, x->x_hist[val]); /* CHECKED: out-of-range numbers are never passed thru */ outlet_float(((t_object *)x)->ob_outlet, val); } } static void Histo_bang(t_Histo *x) { Histo_doit(x, x->x_lastinput, 0); } static void Histo_float(t_Histo *x, t_floatarg f) { int i; if (loud_checkint((t_pd *)x, f, &i, &s_float)) /* CHECKED */ Histo_doit(x, i, 1); } static void Histo_ft1(t_Histo *x, t_floatarg f) { /* CHECKED: floats are accepted in second inlet (truncated) */ Histo_doit(x, (int)f, 0); } static void Histo_free(t_Histo *x) { if (x->x_hist) freebytes(x->x_hist, x->x_size * sizeof(*x->x_hist)); } static void *Histo_new(t_floatarg f) { t_Histo *x; int size = (int)f; unsigned *hist; if (size < 1) /* CHECKED: 1 is allowed */ size = HISTO_DEFSIZE; if (!(hist = (unsigned *)getbytes(size * sizeof(*hist)))) return (0); x = (t_Histo *)pd_new(Histo_class); x->x_size = size; x->x_hist = hist; x->x_lastinput = 0; inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); outlet_new((t_object *)x, &s_float); x->x_countout = outlet_new((t_object *)x, &s_float); Histo_clear(x); return (x); } void Histo_setup(void) { Histo_class = class_new(gensym("Histo"), (t_newmethod)Histo_new, (t_method)Histo_free, sizeof(t_Histo), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)Histo_new, gensym("histo"), A_DEFFLOAT, 0); class_addcreator((t_newmethod)Histo_new, gensym("cyclone/histo"), A_DEFFLOAT, 0); class_addbang(Histo_class, Histo_bang); class_addfloat(Histo_class, Histo_float); class_addmethod(Histo_class, (t_method)Histo_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(Histo_class, (t_method)Histo_clear, gensym("clear"), 0); } void histo_setup(void) { Histo_setup(); } pd-miXedSon-0.2beta3/hammer/MouseState.c000066400000000000000000000102741276723360300201440ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include "m_pd.h" #include "hammer/gui.h" typedef struct _MouseState { t_object x_ob; int x_ispolling; int x_wasbanged; int x_waszeroed; int x_hlast; int x_vlast; int x_hzero; int x_vzero; t_outlet *x_hposout; t_outlet *x_vposout; t_outlet *x_hdiffout; t_outlet *x_vdiffout; } t_MouseState; static t_class *MouseState_class; static void MouseState_anything(t_MouseState *x, t_symbol *s, int ac, t_atom *av) { /* dummy method, filtering out those messages from gui, which are not handled explicitly */ } static void MouseState_doup(t_MouseState *x, t_floatarg f) { outlet_float(((t_object *)x)->ob_outlet, ((int)f ? 0 : 1)); } static void MouseState_dobang(t_MouseState *x, t_floatarg f1, t_floatarg f2) { if (x->x_wasbanged) { int h = (int)f1, v = (int)f2; outlet_float(x->x_vdiffout, v - x->x_vlast); outlet_float(x->x_hdiffout, h - x->x_hlast); outlet_float(x->x_vposout, v - x->x_vzero); outlet_float(x->x_hposout, h - x->x_hzero); x->x_hlast = h; x->x_vlast = v; x->x_wasbanged = 0; } } static void MouseState_dozero(t_MouseState *x, t_floatarg f1, t_floatarg f2) { if (x->x_waszeroed) { int h = (int)f1, v = (int)f2; x->x_hzero = h; x->x_vzero = v; x->x_waszeroed = 0; } } static void MouseState_dopoll(t_MouseState *x, t_floatarg f1, t_floatarg f2) { if (x->x_ispolling) { x->x_wasbanged = 1; MouseState_dobang(x, f1, f2); } } static void MouseState_bang(t_MouseState *x) { hammergui_mousexy(gensym("_bang")); x->x_wasbanged = 1; } static void MouseState_poll(t_MouseState *x) { if (!x->x_ispolling) { x->x_ispolling = 1; hammergui_startpolling((t_pd *)x); } } static void MouseState_nopoll(t_MouseState *x) { if (x->x_ispolling) { x->x_ispolling = 0; hammergui_stoppolling((t_pd *)x); } } static void MouseState_zero(t_MouseState *x) { hammergui_mousexy(gensym("_zero")); x->x_waszeroed = 1; } static void MouseState_reset(t_MouseState *x) { x->x_hzero = x->x_vzero = 0; } static void MouseState_free(t_MouseState *x) { MouseState_nopoll(x); hammergui_unbindmouse((t_pd *)x); } static void *MouseState_new(void) { t_MouseState *x = (t_MouseState *)pd_new(MouseState_class); x->x_ispolling = x->x_wasbanged = x->x_waszeroed = 0; outlet_new((t_object *)x, &s_float); x->x_hposout = outlet_new((t_object *)x, &s_float); x->x_vposout = outlet_new((t_object *)x, &s_float); x->x_hdiffout = outlet_new((t_object *)x, &s_float); x->x_vdiffout = outlet_new((t_object *)x, &s_float); hammergui_bindmouse((t_pd *)x); hammergui_willpoll(); MouseState_reset(x); return (x); } void MouseState_setup(void) { MouseState_class = class_new(gensym("MouseState"), (t_newmethod)MouseState_new, (t_method)MouseState_free, sizeof(t_MouseState), 0, 0); class_addcreator((t_newmethod)MouseState_new, gensym("mousestate"), 0, 0); class_addcreator((t_newmethod)MouseState_new, gensym("cyclone/mousestate"), 0, 0); class_addanything(MouseState_class, MouseState_anything); class_addmethod(MouseState_class, (t_method)MouseState_doup, gensym("_up"), A_FLOAT, 0); class_addmethod(MouseState_class, (t_method)MouseState_dobang, gensym("_bang"), A_FLOAT, A_FLOAT, 0); class_addmethod(MouseState_class, (t_method)MouseState_dozero, gensym("_zero"), A_FLOAT, A_FLOAT, 0); class_addmethod(MouseState_class, (t_method)MouseState_dopoll, gensym("_poll"), A_FLOAT, A_FLOAT, 0); class_addbang(MouseState_class, MouseState_bang); class_addmethod(MouseState_class, (t_method)MouseState_poll, gensym("poll"), 0); class_addmethod(MouseState_class, (t_method)MouseState_nopoll, gensym("nopoll"), 0); class_addmethod(MouseState_class, (t_method)MouseState_zero, gensym("zero"), 0); class_addmethod(MouseState_class, (t_method)MouseState_reset, gensym("reset"), 0); } void mousestate_setup(void) { MouseState_setup(); } pd-miXedSon-0.2beta3/hammer/Peak.c000066400000000000000000000033261276723360300167330ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include "m_pd.h" #define PEAK_INITIAL 0 typedef struct _Peak { t_object x_ob; t_float x_value; t_outlet *x_out2; t_outlet *x_out3; } t_Peak; static t_class *Peak_class; static void Peak_bang(t_Peak *x) { outlet_float(((t_object *)x)->ob_outlet, x->x_value); } static void Peak_ft1(t_Peak *x, t_floatarg f) { /* CHECKME loud_checkint */ outlet_float(x->x_out3, 0); /* CHECKME */ outlet_float(x->x_out2, 1); outlet_float(((t_object *)x)->ob_outlet, x->x_value = f); } static void Peak_float(t_Peak *x, t_float f) { /* CHECKME loud_checkint */ if (f > x->x_value) Peak_ft1(x, f); else { outlet_float(x->x_out3, 1); outlet_float(x->x_out2, 0); } } static void *Peak_new(t_floatarg f) { t_Peak *x = (t_Peak *)pd_new(Peak_class); x->x_value = PEAK_INITIAL; inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); outlet_new((t_object *)x, &s_float); x->x_out2 = outlet_new((t_object *)x, &s_float); x->x_out3 = outlet_new((t_object *)x, &s_float); return (x); } void Peak_setup(void) { Peak_class = class_new(gensym("Peak"), (t_newmethod)Peak_new, 0, sizeof(t_Peak), 0, 0); class_addcreator((t_newmethod)Peak_new, gensym("peak"), 0, 0); class_addcreator((t_newmethod)Peak_new, gensym("cyclone/peak"), 0, 0); class_addbang(Peak_class, Peak_bang); class_addfloat(Peak_class, Peak_float); class_addmethod(Peak_class, (t_method)Peak_ft1, gensym("ft1"), A_FLOAT, 0); } void peak_setup(void) { Peak_setup(); } pd-miXedSon-0.2beta3/hammer/Table.c000066400000000000000000000632511276723360300171050ustar00rootroot00000000000000/* Copyright (c) 2004-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* Write access is totally encapsulated in tablecommon calls, in order to simplify proper handling of the distribution cache. Direct read access from table calls is allowed (for speed). */ #include #include #include "m_pd.h" #include "g_canvas.h" #include "common/loud.h" #include "common/grow.h" #include "common/rand.h" #include "hammer/file.h" #ifdef KRZYSZCZ #define TABLE_DEBUG #endif #define TABLE_INISIZE 256 /* LATER rethink */ #define TABLE_DEFLENGTH 128 /* CHECKED */ #define TABLE_MINLENGTH 2 /* CHECKED */ #define TABLE_MAXLENGTH 16383 /* CHECKED, LATER rethink */ #define TABLE_MINRANGE 2 /* CHECKED */ #define TABLE_MAXQ 32768 /* CHECKME */ typedef struct _tablecommon { t_pd c_pd; struct _table *c_refs; int c_increation; int c_volatile; int c_selfmodified; int c_entered; /* a counter, LATER rethink */ /* CHECKED flags, etc. are common fields */ int c_visflag; int c_embedflag; int c_dontsaveflag; int c_notenamesflag; int c_signedflag; int c_range; int c_left; int c_top; int c_right; int c_bottom; int c_size; /* as allocated */ int c_length; /* as used */ int *c_table; int c_tableini[TABLE_INISIZE]; int c_cacheisfresh; int c_cachesum; int c_cachemin; int c_cachemax; int *c_cache; int c_cacheini[TABLE_INISIZE]; t_symbol *c_filename; t_canvas *c_lastcanvas; t_hammerfile *c_filehandle; } t_tablecommon; typedef struct _table { t_object x_ob; t_canvas *x_glist; t_symbol *x_name; t_tablecommon *x_common; t_float x_value; int x_valueset; int x_head; int x_intraversal; /* ``set-with-next/prev'' flag */ int x_loadflag; int x_loadndx; unsigned int x_seed; t_hammerfile *x_filehandle; t_outlet *x_bangout; struct _table *x_next; } t_table; static t_class *table_class; static t_class *tablecommon_class; static void tablecommon_modified(t_tablecommon *cc, int relocated) { cc->c_cacheisfresh = 0; if (cc->c_increation) return; if (relocated) { cc->c_volatile = 1; } if (cc->c_embedflag) { t_table *x; for (x = cc->c_refs; x; x = x->x_next) if (x->x_glist && glist_isvisible(x->x_glist)) canvas_dirty(x->x_glist, 1); } } static int tablecommon_getindex(t_tablecommon *cc, int ndx) { int nmx = cc->c_length - 1; /* CHECKED ndx silently clipped */ return (ndx < 0 ? 0 : (ndx > nmx ? nmx : ndx)); } static int tablecommon_getvalue(t_tablecommon *cc, int ndx) { int nmx = cc->c_length - 1; /* CHECKED ndx silently clipped */ return (cc->c_table[ndx < 0 ? 0 : (ndx > nmx ? nmx : ndx)]); } static void tablecommon_setvalue(t_tablecommon *cc, int ndx, int v) { int nmx = cc->c_length - 1; /* CHECKED ndx silently clipped, value not clipped */ cc->c_table[ndx < 0 ? 0 : (ndx > nmx ? nmx : ndx)] = v; tablecommon_modified(cc, 0); } static int tablecommon_loadvalue(t_tablecommon *cc, int ndx, int v) { /* CHECKME */ if (ndx < cc->c_length) { cc->c_table[ndx] = v; tablecommon_modified(cc, 0); return (1); } else return (0); } static void tablecommon_setall(t_tablecommon *cc, int v) { int ndx = cc->c_length; int *ptr = cc->c_table; while (ndx--) *ptr++ = v; tablecommon_modified(cc, 0); } static void tablecommon_setatoms(t_tablecommon *cc, int ndx, int ac, t_atom *av) { if (ac > 1 && av->a_type == A_FLOAT) { /* CHECKED no resizing */ int last = tablecommon_getindex(cc, ndx + ac - 1); int *ptr = cc->c_table + ndx; for (; ndx <= last; ndx++, av++) *ptr++ = (av->a_type == A_FLOAT ? (int)av->a_w.w_float : 0); tablecommon_modified(cc, 0); } } static void tablecommon_setlength(t_tablecommon *cc, int length) { int relocate; if (length < TABLE_MINLENGTH) length = TABLE_MINLENGTH; else if (length > TABLE_MAXLENGTH) length = TABLE_MAXLENGTH; if (relocate = (length > cc->c_size)) { int l = length; /* CHECKED existing values are preserved */ cc->c_table = grow_withdata(&length, &cc->c_length, &cc->c_size, cc->c_table, TABLE_INISIZE, cc->c_tableini, sizeof(*cc->c_table)); if (length == l) cc->c_table = grow_nodata(&length, &cc->c_size, cc->c_cache, TABLE_INISIZE, cc->c_cacheini, sizeof(*cc->c_cache)); if (length != l) { if (cc->c_table != cc->c_tableini) freebytes(cc->c_table, cc->c_size * sizeof(*cc->c_table)); if (cc->c_cache != cc->c_cacheini) freebytes(cc->c_cache, cc->c_size * sizeof(*cc->c_cache)); cc->c_size = length = TABLE_INISIZE; cc->c_table = cc->c_tableini; cc->c_cache = cc->c_cacheini; } } cc->c_length = length; /* CHECKED values at common indices are preserved */ /* CHECKED rewinding neither head, nor loadndx -- both are preserved, although there is a bug in handling of 'prev' after the head overflows due to shrinking. */ tablecommon_modified(cc, relocate); } static void tablecommon_cacheupdate(t_tablecommon *cc) { int ndx = cc->c_length, sum = 0, mn, mx; int *tptr = cc->c_table, *cptr = cc->c_cache; mn = mx = *tptr; while (ndx--) { int v = *tptr++; *cptr++ = (sum += v); if (mn > v) mn = v; else if (mx < v) mx = v; } cc->c_cachesum = sum; cc->c_cachemin = mn; cc->c_cachemax = mx; cc->c_cacheisfresh = 1; } static int tablecommon_quantile(t_tablecommon *cc, float f) { /* CHECKME */ float fv; int ndx, *ptr, nmx = cc->c_length - 1; if (!cc->c_cacheisfresh) tablecommon_cacheupdate(cc); fv = f * cc->c_cachesum; for (ndx = 0, ptr = cc->c_cache; ndx < nmx; ndx++, ptr++) if (*ptr >= fv) break; return (ndx); } static void tablecommon_fromatoms(t_tablecommon *cc, int ac, t_atom *av) { int i, size = 0, nsyms = 0; t_atom *ap; int *ptr; cc->c_increation = 1; for (i = 0, ap = av; i < ac; i++, ap++) { if (ap->a_type == A_FLOAT) size++; else if (ap->a_type == A_SYMBOL) nsyms++, size++; } if (size < ac) loud_warning(0, "Table", "%d invalid atom%s ignored", ac - size, (ac - size > 1 ? "s" : "")); if (nsyms) loud_warning(0, "Table", "%d symbol%s bashed to zero", nsyms, (nsyms > 1 ? "s" : "")); tablecommon_setlength(cc, size); size = cc->c_length; ptr = cc->c_table; for (i = 0; i < ac; i++, av++) { if (av->a_type == A_FLOAT) *ptr++ = (int)av->a_w.w_float; else if (av->a_type == A_SYMBOL) *ptr++ = 0; else continue; if (size-- == 1) break; } while (size--) *ptr++ = 0; cc->c_increation = 0; } /* FIXME keep int precision: save/load directly, not through a bb */ /* LATER binary files */ static void tablecommon_doread(t_tablecommon *cc, t_symbol *fn, t_canvas *cv) { t_binbuf *bb = binbuf_new(); int ac; t_atom *av; char buf[MAXPDSTRING]; if (!fn) return; /* CHECKME complaint */ /* FIXME use open_via_path() */ if (cv || (cv = cc->c_lastcanvas)) /* !cv: 'read' w/o arg */ canvas_makefilename(cv, fn->s_name, buf, MAXPDSTRING); else { strncpy(buf, fn->s_name, MAXPDSTRING); buf[MAXPDSTRING-1] = 0; } binbuf_read(bb, buf, "", 0); if ((ac = binbuf_getnatom(bb)) && (av = binbuf_getvec(bb)) && av->a_type == A_SYMBOL && av->a_w.w_symbol == gensym("table")) { tablecommon_fromatoms(cc, ac - 1, av + 1); post("Table: %s read successful", fn->s_name); /* CHECKME */ } #if 0 /* FIXME */ else /* CHECKME complaint */ loud_error((t_pd *)cc, "invalid file %s", fn->s_name); #endif binbuf_free(bb); } static void tablecommon_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { tablecommon_doread((t_tablecommon *)z, fn, 0); } static void tablecommon_dowrite(t_tablecommon *cc, t_symbol *fn, t_canvas *cv) { t_binbuf *bb = binbuf_new(); char buf[MAXPDSTRING]; int ndx, *ptr; if (!fn) return; /* CHECKME complaint */ if (cv || (cv = cc->c_lastcanvas)) /* !cv: 'write' w/o arg */ canvas_makefilename(cv, fn->s_name, buf, MAXPDSTRING); else { strncpy(buf, fn->s_name, MAXPDSTRING); buf[MAXPDSTRING-1] = 0; } binbuf_addv(bb, "s", atom_getsymbol(binbuf_getvec(cc->c_refs->x_ob.te_binbuf))); for (ndx = 0, ptr = cc->c_table; ndx < cc->c_length; ndx++, ptr++) binbuf_addv(bb, "i", *ptr); binbuf_write(bb, buf, "", 0); binbuf_free(bb); } static void tablecommon_writehook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { tablecommon_dowrite((t_tablecommon *)z, fn, 0); } static void table_embedhook(t_pd *z, t_binbuf *bb, t_symbol *bindsym) { t_table *x = (t_table *)z; t_tablecommon *cc = x->x_common; if (cc->c_embedflag) { int ndx = 0, left = cc->c_length; int *ptr = cc->c_table; binbuf_addv(bb, "ssi;", bindsym, gensym("size"), cc->c_length); binbuf_addv(bb, "ssiiii;", bindsym, gensym("flags"), 1, cc->c_dontsaveflag, cc->c_notenamesflag, cc->c_signedflag); binbuf_addv(bb, "ssi;", bindsym, gensym("tabrange"), cc->c_range); binbuf_addv(bb, "ssiiiii;", bindsym, gensym("_coords"), cc->c_left, cc->c_top, cc->c_right, cc->c_bottom, cc->c_visflag); while (left > 0) { int cnt = (left > 128 ? 128 : left); left -= cnt; ndx += cnt; binbuf_addv(bb, "ssi", bindsym, gensym("set"), ndx); while (cnt--) { t_atom at; SETFLOAT(&at, (float)*ptr); binbuf_add(bb, 1, &at); ptr++; } binbuf_addsemi(bb); } } } static void tablecommon_editorhook(t_pd *z, t_symbol *s, int ac, t_atom *av) { tablecommon_fromatoms((t_tablecommon *)z, ac, av); } static void tablecommon_free(t_tablecommon *cc) { if (cc->c_table != cc->c_tableini) freebytes(cc->c_table, cc->c_size * sizeof(*cc->c_table)); if (cc->c_cache != cc->c_cacheini) freebytes(cc->c_cache, cc->c_size * sizeof(*cc->c_cache)); } static void *tablecommon_new(void) { t_tablecommon *cc = (t_tablecommon *)pd_new(tablecommon_class); cc->c_visflag = 0; cc->c_embedflag = 0; cc->c_dontsaveflag = 0; cc->c_notenamesflag = 0; cc->c_signedflag = 0; cc->c_size = TABLE_INISIZE; cc->c_length = TABLE_DEFLENGTH; cc->c_table = cc->c_tableini; cc->c_cache = cc->c_cacheini; cc->c_cacheisfresh = 0; return (cc); } static t_tablecommon *table_checkcommon(t_table *x) { if (x->x_name && x->x_common != (t_tablecommon *)pd_findbyclass(x->x_name, tablecommon_class)) { loudbug_bug("table_checkcommon"); return (0); } return (x->x_common); } static void table_unbind(t_table *x) { /* LATER consider calling table_checkcommon(x) */ t_tablecommon *cc = x->x_common; t_table *prev, *next; if ((prev = cc->c_refs) == x) { if (!(cc->c_refs = x->x_next)) { hammerfile_free(cc->c_filehandle); tablecommon_free(cc); if (x->x_name) pd_unbind(&cc->c_pd, x->x_name); pd_free(&cc->c_pd); } } else if (prev) { while (next = prev->x_next) { if (next == x) { prev->x_next = next->x_next; break; } prev = next; } } x->x_common = 0; x->x_name = 0; x->x_next = 0; } static void table_bind(t_table *x, t_symbol *name) { t_tablecommon *cc = 0; if (name == &s_) name = 0; else if (name) cc = (t_tablecommon *)pd_findbyclass(name, tablecommon_class); if (!cc) { cc = (t_tablecommon *)tablecommon_new(); cc->c_refs = 0; cc->c_increation = 0; if (name) { pd_bind(&cc->c_pd, name); /* LATER rethink canvas unpredictability */ tablecommon_doread(cc, name, x->x_glist); } else { cc->c_filename = 0; cc->c_lastcanvas = 0; } cc->c_filehandle = hammerfile_new((t_pd *)cc, 0, tablecommon_readhook, tablecommon_writehook, tablecommon_editorhook); } x->x_common = cc; x->x_name = name; x->x_next = cc->c_refs; cc->c_refs = x; } static int table_rebind(t_table *x, t_symbol *name) { t_tablecommon *cc; if (name && name != &s_ && (cc = (t_tablecommon *)pd_findbyclass(name, tablecommon_class))) { table_unbind(x); x->x_common = cc; x->x_name = name; x->x_next = cc->c_refs; cc->c_refs = x; return (1); } else return (0); } static void table_dooutput(t_table *x, int ndx) { outlet_float(((t_object *)x)->ob_outlet, (t_float)tablecommon_getvalue(x->x_common, ndx)); } static void table_bang(t_table *x) { /* CHECKME */ outlet_float(((t_object *)x)->ob_outlet, (t_float)tablecommon_quantile(x->x_common, rand_unipolar(&x->x_seed))); } static void table_float(t_table *x, t_float f) { if (x->x_loadflag) { /* CHECKME */ if (tablecommon_loadvalue(x->x_common, x->x_loadndx, (int)f)) x->x_loadndx++; } else { int ndx = (int)f; /* CHECKED floats are truncated */ if (x->x_valueset) { tablecommon_setvalue(x->x_common, ndx, x->x_value); x->x_valueset = 0; } else table_dooutput(x, ndx); /* CHECKED head is not updated */ } } static void table_ft1(t_table *x, t_floatarg f) { x->x_value = (int)f; /* CHECKED floats are truncated */ x->x_valueset = 1; } static void table_size(t_table *x, t_floatarg f) { tablecommon_setlength(x->x_common, (int)f); } static void table_set(t_table *x, t_symbol *s, int ac, t_atom *av) { if (ac > 1 && av->a_type == A_FLOAT) { int ndx = tablecommon_getindex(x->x_common, (int)av->a_w.w_float); tablecommon_setatoms(x->x_common, ndx, ac - 1, av + 1); } } static void table_flags(t_table *x, t_symbol *s, int ac, t_atom *av) { t_tablecommon *cc = x->x_common; int i = 0, v; while (ac && av->a_type == A_FLOAT && loud_checkint((t_pd *)x, av->a_w.w_float, &v, gensym("flags"))) { /* CHECKED order, modifying only explicitly specified flags */ if (i == 0) cc->c_embedflag = (v != 0); else if (i == 1) cc->c_dontsaveflag = (v != 0); else if (i == 2) cc->c_notenamesflag = (v != 0); else if (i == 3) cc->c_signedflag = (v != 0); else break; i++; ac--; av++; } } static void table_tabrange(t_table *x, t_floatarg f) { int i = (int)f; x->x_common->c_range = (i > TABLE_MINRANGE ? i : TABLE_MINRANGE); } static void table__coords(t_table *x, t_floatarg fl, t_floatarg ft, t_floatarg fr, t_floatarg fb, t_floatarg fv) { t_tablecommon *cc = x->x_common; /* FIXME constraints */ cc->c_left = (int)fl; cc->c_top = (int)ft; cc->c_right = (int)fr; cc->c_bottom = (int)fb; cc->c_visflag = ((int)fv != 0); } static void table_cancel(t_table *x) { x->x_valueset = 0; } static void table_clear(t_table *x) { tablecommon_setall(x->x_common, 0); /* CHECKED head preserved */ } static void table_const(t_table *x, t_floatarg f) { tablecommon_setall(x->x_common, (int)f); /* CHECKED head preserved */ } static void table_load(t_table *x) { x->x_loadflag = 1; x->x_loadndx = 0; /* CHECKED rewind, head not affected */ } static void table_normal(t_table *x) { x->x_loadflag = 0; } static void table_next(t_table *x) { if (!x->x_intraversal) x->x_intraversal = 1; else if (++x->x_head >= x->x_common->c_length) x->x_head = 0; table_dooutput(x, x->x_head); } static void table_prev(t_table *x) { if (!x->x_intraversal) x->x_intraversal = 1; else if (--x->x_head < 0) x->x_head = x->x_common->c_length - 1; table_dooutput(x, x->x_head); } static void table_goto(t_table *x, t_floatarg f) { /* CHECKED floats are truncated */ x->x_head = tablecommon_getindex(x->x_common, (int)f); /* CHECKED the head should be pre-updated during traversal, in order to maintain the logical way of direction change. Therefore, we need the flag below, which locks head in place that has just been set by goto. The flag is then set by next or prev. */ x->x_intraversal = 0; } static void table_send(t_table *x, t_symbol *s, int ac, t_atom *av) { if (ac > 1 && av->a_type == A_SYMBOL) { t_symbol *target = av->a_w.w_symbol; if (!target->s_thing) return; /* CHECKED no complaint */ ac--; av++; if (av->a_type == A_FLOAT) { if (ac == 1) { int ndx = (int)av->a_w.w_float; pd_float(target->s_thing, (t_float)tablecommon_getvalue(x->x_common, ndx)); } /* CHECKED incompatible: 'send ' stores at (a bug?) */ } else if (av->a_type == A_SYMBOL) { /* CHECKED 'send length' works, but not max, min, sum... */ if (av->a_w.w_symbol == gensym("length")) pd_float(target->s_thing, (t_float)x->x_common->c_length); } } } static void table_length(t_table *x) { outlet_float(((t_object *)x)->ob_outlet, (t_float)x->x_common->c_length); } static void table_sum(t_table *x) { t_tablecommon *cc = x->x_common; if (!cc->c_cacheisfresh) tablecommon_cacheupdate(cc); outlet_float(((t_object *)x)->ob_outlet, (t_float)cc->c_cachesum); } static void table_min(t_table *x) { t_tablecommon *cc = x->x_common; if (!cc->c_cacheisfresh) tablecommon_cacheupdate(cc); outlet_float(((t_object *)x)->ob_outlet, (t_float)cc->c_cachemin); } static void table_max(t_table *x) { t_tablecommon *cc = x->x_common; if (!cc->c_cacheisfresh) tablecommon_cacheupdate(cc); outlet_float(((t_object *)x)->ob_outlet, (t_float)cc->c_cachemax); } static void table_getbits(t_table *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) { /* FIXME */ } static void table_setbits(t_table *x, t_floatarg f1, t_floatarg f2, t_floatarg f3, t_floatarg f4) { /* FIXME */ } static void table_inv(t_table *x, t_floatarg f) { /* CHECKME none found, float */ int v = (int)f, ndx, *ptr, nmx = x->x_common->c_length - 1; for (ndx = 0, ptr = x->x_common->c_table; ndx < nmx; ndx++, ptr++) if (*ptr >= v) break; outlet_float(((t_object *)x)->ob_outlet, (t_float)ndx); } static void table_quantile(t_table *x, t_floatarg f) { /* CHECKME */ outlet_float(((t_object *)x)->ob_outlet, (t_float)tablecommon_quantile(x->x_common, f / ((float)TABLE_MAXQ))); } static void table_fquantile(t_table *x, t_floatarg f) { /* CHECKME constraints */ outlet_float(((t_object *)x)->ob_outlet, (t_float)tablecommon_quantile(x->x_common, f)); } static void table_dump(t_table *x, t_symbol *s, int ac, t_atom *av) { t_tablecommon *cc = x->x_common; int thelength = cc->c_length; int *thetable = cc->c_table; t_outlet *out = ((t_object *)x)->ob_outlet; int ndx, nmx, *ptr; /* CHECKED optional arguments: from, to, Negative 'from' causes invalid output, symbols are bashed to zero for both arguments, inconsistent warnings, etc. -- no strict emulation attempted below. */ if (ac && av->a_type == A_FLOAT) ndx = tablecommon_getindex(cc, (int)av->a_w.w_float); else ndx = 0; if (ac > 1 && av[1].a_type == A_FLOAT) nmx = tablecommon_getindex(cc, (int)av[1].a_w.w_float); else nmx = thelength - 1; for (ptr = thetable + ndx; ndx <= nmx; ndx++, ptr++) { /* Plain traversing by incrementing a pointer is not robust, because calling outlet_float() may invalidate the pointer. Continous storage does not require generic selfmod detection (ala coll), so we can get away with the simpler test below. */ if (cc->c_length != thelength || cc->c_table != thetable) break; /* CHECKED no remote dumping */ outlet_float(out, (t_float)*ptr); } } static void table_refer(t_table *x, t_symbol *s) { if (!table_rebind(x, s)) { /* LATER consider complaining */ } } static void table_read(t_table *x, t_symbol *s) { t_tablecommon *cc = x->x_common; if (s && s != &s_) tablecommon_doread(cc, s, x->x_glist); else hammerpanel_open(cc->c_filehandle, 0); } static void table_write(t_table *x, t_symbol *s) { t_tablecommon *cc = x->x_common; if (s && s != &s_) tablecommon_dowrite(cc, s, x->x_glist); else hammerpanel_save(cc->c_filehandle, 0, 0); } static int tablecommon_editorappend(t_tablecommon *cc, int v, char *buf, int col) { char *bp = buf; int cnt = 0; if (col > 0) *bp++ = ' ', cnt++; cnt += sprintf(bp, "%d", v); if (col + cnt > 80) buf[0] = '\n', col = cnt - 1; /* assuming col > 0 */ else col += cnt; hammereditor_append(cc->c_filehandle, buf); return (col); } static void table_open(t_table *x) { t_tablecommon *cc = x->x_common; char buf[MAXPDSTRING]; int *bp = cc->c_table; int count = cc->c_length, col = 0; hammereditor_open(cc->c_filehandle, (x->x_name ? x->x_name->s_name : 0), 0); while (count--) col = tablecommon_editorappend(cc, *bp++, buf, col); hammereditor_setdirty(cc->c_filehandle, 0); } static void table_wclose(t_table *x) { hammereditor_close(x->x_common->c_filehandle, 1); } static void table_click(t_table *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) { table_open(x); } #ifdef TABLE_DEBUG static void table_debug(t_table *x, t_floatarg f) { t_tablecommon *cc = table_checkcommon(x); if (cc) { t_table *x1 = cc->c_refs; int i = 0; while (x1) i++, x1 = x1->x_next; loudbug_post("refcount %d", i); } } #endif static void table_free(t_table *x) { hammerfile_free(x->x_filehandle); table_unbind(x); } static void *table_new(t_symbol *s) { t_table *x = (t_table *)pd_new(table_class); static int warned = 0; if (!warned) { loud_warning((t_pd *)x, 0, "Table is not ready yet"); warned = 1; } x->x_glist = canvas_getcurrent(); x->x_valueset = 0; x->x_head = 0; x->x_intraversal = 0; /* CHECKED */ x->x_loadflag = 0; rand_seed(&x->x_seed, 0); inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); outlet_new((t_object *)x, &s_float); x->x_bangout = outlet_new((t_object *)x, &s_bang); x->x_filehandle = hammerfile_new((t_pd *)x, table_embedhook, 0, 0, 0); table_bind(x, s); return (x); } void Table_setup(void) { table_class = class_new(gensym("Table"), (t_newmethod)table_new, (t_method)table_free, sizeof(t_table), 0, A_DEFSYM, 0); class_addbang(table_class, table_bang); class_addfloat(table_class, table_float); class_addmethod(table_class, (t_method)table_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(table_class, (t_method)table_size, gensym("size"), A_FLOAT, 0); class_addmethod(table_class, (t_method)table_set, gensym("set"), A_GIMME, 0); class_addmethod(table_class, (t_method)table_flags, gensym("flags"), A_GIMME, 0); class_addmethod(table_class, (t_method)table_tabrange, gensym("tabrange"), A_FLOAT, 0); class_addmethod(table_class, (t_method)table__coords, gensym("_coords"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); class_addmethod(table_class, (t_method)table_cancel, gensym("cancel"), 0); class_addmethod(table_class, (t_method)table_clear, gensym("clear"), 0); class_addmethod(table_class, (t_method)table_const, gensym("const"), A_FLOAT, 0); class_addmethod(table_class, (t_method)table_load, gensym("load"), 0); class_addmethod(table_class, (t_method)table_normal, gensym("normal"), 0); class_addmethod(table_class, (t_method)table_next, gensym("next"), 0); class_addmethod(table_class, (t_method)table_prev, gensym("prev"), 0); class_addmethod(table_class, (t_method)table_goto, gensym("goto"), A_FLOAT, 0); class_addmethod(table_class, (t_method)table_send, gensym("send"), A_GIMME, 0); class_addmethod(table_class, (t_method)table_length, gensym("length"), 0); class_addmethod(table_class, (t_method)table_sum, gensym("sum"), 0); class_addmethod(table_class, (t_method)table_min, gensym("min"), 0); class_addmethod(table_class, (t_method)table_max, gensym("max"), 0); class_addmethod(table_class, (t_method)table_getbits, gensym("getbits"), A_FLOAT, A_FLOAT, A_FLOAT, 0); class_addmethod(table_class, (t_method)table_setbits, gensym("setbits"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); class_addmethod(table_class, (t_method)table_inv, gensym("inv"), A_FLOAT, 0); class_addmethod(table_class, (t_method)table_quantile, gensym("quantile"), A_FLOAT, 0); class_addmethod(table_class, (t_method)table_fquantile, gensym("fquantile"), A_FLOAT, 0); class_addmethod(table_class, (t_method)table_dump, gensym("dump"), A_GIMME, 0); class_addmethod(table_class, (t_method)table_refer, gensym("refer"), A_SYMBOL, 0); class_addmethod(table_class, (t_method)table_read, gensym("read"), A_DEFSYM, 0); class_addmethod(table_class, (t_method)table_write, gensym("write"), A_DEFSYM, 0); class_addmethod(table_class, (t_method)table_open, gensym("open"), 0); class_addmethod(table_class, (t_method)table_wclose, gensym("wclose"), 0); class_addmethod(table_class, (t_method)table_click, gensym("click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); #ifdef TABLE_DEBUG class_addmethod(table_class, (t_method)table_debug, gensym("debug"), A_DEFFLOAT, 0); #endif hammerfile_setup(table_class, 1); tablecommon_class = class_new(gensym("Table"), 0, 0, sizeof(t_tablecommon), CLASS_PD, 0); /* this call is a nop (tablecommon does not embed, and the hammerfile class itself has been already set up above), but it is better to have it around, just in case... */ hammerfile_setup(tablecommon_class, 0); } pd-miXedSon-0.2beta3/hammer/TogEdge.c000066400000000000000000000031031276723360300173620ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include "m_pd.h" #include "common/loud.h" typedef struct _TogEdge { t_object x_ob; int x_wason; t_outlet *x_out1; } t_TogEdge; static t_class *TogEdge_class; static void TogEdge_bang(t_TogEdge *x) { if (x->x_wason) { x->x_wason = 0; outlet_bang(x->x_out1); } else { x->x_wason = 1; outlet_bang(((t_object *)x)->ob_outlet); } } static void TogEdge_float(t_TogEdge *x, t_float f) { int i; if (loud_checkint((t_pd *)x, f, &i, &s_float)) /* CHECKED */ { if (x->x_wason) { if (!i) { x->x_wason = 0; outlet_bang(x->x_out1); } } else { if (i) { x->x_wason = 1; outlet_bang(((t_object *)x)->ob_outlet); } } } } static void *TogEdge_new(void) { t_TogEdge *x = (t_TogEdge *)pd_new(TogEdge_class); x->x_wason = 0; /* CHECKED */ outlet_new((t_object *)x, &s_bang); x->x_out1 = outlet_new((t_object *)x, &s_bang); return (x); } void TogEdge_setup(void) { TogEdge_class = class_new(gensym("TogEdge"), (t_newmethod)TogEdge_new, 0, sizeof(t_TogEdge), 0, 0); class_addcreator((t_newmethod)TogEdge_new, gensym("togedge"), 0, 0); class_addcreator((t_newmethod)TogEdge_new, gensym("cyclone/togedge"), 0, 0); class_addbang(TogEdge_class, TogEdge_bang); class_addfloat(TogEdge_class, TogEdge_float); } void togedge_setup(void) { TogEdge_setup(); } pd-miXedSon-0.2beta3/hammer/Trough.c000066400000000000000000000034551276723360300173260ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include "m_pd.h" #define TROUGH_INITIAL 128 /* CHECKME */ typedef struct _Trough { t_object x_ob; t_float x_value; t_outlet *x_out2; t_outlet *x_out3; } t_Trough; static t_class *Trough_class; static void Trough_bang(t_Trough *x) { outlet_float(((t_object *)x)->ob_outlet, x->x_value); } static void Trough_ft1(t_Trough *x, t_floatarg f) { /* CHECKME loud_checkint */ outlet_float(x->x_out3, 0); /* CHECKME */ outlet_float(x->x_out2, 1); outlet_float(((t_object *)x)->ob_outlet, x->x_value = f); } static void Trough_float(t_Trough *x, t_float f) { /* CHECKME loud_checkint */ if (f < x->x_value) Trough_ft1(x, f); else { outlet_float(x->x_out3, 1); outlet_float(x->x_out2, 0); } } static void *Trough_new(t_floatarg f) { t_Trough *x = (t_Trough *)pd_new(Trough_class); x->x_value = TROUGH_INITIAL; inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); outlet_new((t_object *)x, &s_float); x->x_out2 = outlet_new((t_object *)x, &s_float); x->x_out3 = outlet_new((t_object *)x, &s_float); return (x); } void Trough_setup(void) { Trough_class = class_new(gensym("Trough"), (t_newmethod)Trough_new, 0, sizeof(t_Trough), 0, 0); class_addcreator((t_newmethod)Trough_new, gensym("trough"), 0, 0); class_addcreator((t_newmethod)Trough_new, gensym("cyclone/trough"), 0, 0); class_addbang(Trough_class, Trough_bang); class_addfloat(Trough_class, Trough_float); class_addmethod(Trough_class, (t_method)Trough_ft1, gensym("ft1"), A_FLOAT, 0); } void trough_setup(void) { Trough_setup(); } pd-miXedSon-0.2beta3/hammer/Uzi.c000066400000000000000000000056771276723360300166350ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* CHECKME negative 'nbangs' value set during run-time */ #include "m_pd.h" typedef struct _Uzi { t_object x_obj; t_float x_nbangs; int x_count; int x_running; t_outlet *x_out2; t_outlet *x_out3; } t_Uzi; static t_class *Uzi_class; #define UZI_RUNNING 1 #define UZI_PAUSED 2 static void Uzi_dobang(t_Uzi *x) { /* CHECKME reentrancy */ if (!x->x_running) { int count, nbangs = (int)x->x_nbangs; x->x_running = UZI_RUNNING; for (count = x->x_count + 1; count <= nbangs; count++) { outlet_float(x->x_out3, count); outlet_bang(((t_object *)x)->ob_outlet); if (x->x_running == UZI_PAUSED) { /* CHECKED: carry bang not sent, even if this is last bang */ x->x_count = count; return; } } /* CHECKED: carry bang sent also when there are no left-outlet bangs */ /* CHECKED: sent after left outlet, not before */ outlet_bang(x->x_out2); x->x_count = 0; x->x_running = 0; } } static void Uzi_bang(t_Uzi *x) { /* CHECKED: always restarts (when paused too) */ x->x_count = 0; x->x_running = 0; Uzi_dobang(x); } static void Uzi_float(t_Uzi *x, t_float f) { /* CHECKED: always sets a new value and restarts (when paused too) */ x->x_nbangs = f; Uzi_bang(x); } /* CHECKED: 'pause, resume' (but not just 'resume') sends a carry bang when not running (a bug?) */ static void Uzi_pause(t_Uzi *x) { if (!x->x_running) x->x_count = (int)x->x_nbangs; /* bug emulation? */ x->x_running = UZI_PAUSED; } static void Uzi_resume(t_Uzi *x) { if (x->x_running == UZI_PAUSED) { x->x_running = 0; Uzi_dobang(x); } } static void *Uzi_new(t_floatarg f) { t_Uzi *x = (t_Uzi *)pd_new(Uzi_class); x->x_nbangs = (f > 1. ? f : 1.); x->x_count = 0; x->x_running = 0; /* CHECKED: set when paused, but then 'resume' is blocked (a bug?) */ floatinlet_new((t_object *)x, &x->x_nbangs); outlet_new((t_object *)x, &s_bang); x->x_out2 = outlet_new((t_object *)x, &s_bang); x->x_out3 = outlet_new((t_object *)x, &s_float); return (x); } void Uzi_setup(void) { Uzi_class = class_new(gensym("Uzi"), (t_newmethod)Uzi_new, 0, sizeof(t_Uzi), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)Uzi_new, gensym("uzi"), A_DEFFLOAT, 0); class_addcreator((t_newmethod)Uzi_new, gensym("cyclone/uzi"), A_DEFFLOAT, 0); class_addbang(Uzi_class, Uzi_bang); class_addfloat(Uzi_class, Uzi_float); class_addmethod(Uzi_class, (t_method)Uzi_pause, gensym("pause"), 0); class_addmethod(Uzi_class, (t_method)Uzi_pause, gensym("break"), 0); class_addmethod(Uzi_class, (t_method)Uzi_resume, gensym("resume"), 0); class_addmethod(Uzi_class, (t_method)Uzi_resume, gensym("continue"), 0); } void uzi_setup(void) { Uzi_setup(); } pd-miXedSon-0.2beta3/hammer/accum.c000066400000000000000000000033671276723360300171500ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* This is a slightly edited version of Joseph A. Sarlo's code. The most important changes are listed in "pd-lib-notes.txt" file. */ #include "m_pd.h" typedef struct _accum { t_object x_ob; t_float x_total; } t_accum; static t_class *accum_class; static void accum_set(t_accum *x, t_floatarg val) { x->x_total = val; } static void accum_bang(t_accum *x) { outlet_float(((t_object *)x)->ob_outlet, x->x_total); } static void accum_float(t_accum *x, t_floatarg val) { /* LATER reconsider int/float dilemma */ accum_set(x, val); accum_bang(x); } static void accum_add(t_accum *x, t_floatarg val) { /* LATER reconsider int/float dilemma */ x->x_total += val; } static void accum_mult(t_accum *x, t_floatarg val) { x->x_total *= val; } static void *accum_new(t_floatarg val) { t_accum *x = (t_accum *)pd_new(accum_class); x->x_total = val; inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft2")); outlet_new((t_object *)x, &s_float); return (x); } void accum_setup(void) { accum_class = class_new(gensym("accum"), (t_newmethod)accum_new, 0, sizeof(t_accum), 0, A_DEFFLOAT, 0); class_addbang(accum_class, accum_bang); class_addfloat(accum_class, accum_float); class_addmethod(accum_class, (t_method)accum_add, gensym("ft1"), A_FLOAT, 0); class_addmethod(accum_class, (t_method)accum_mult, gensym("ft2"), A_FLOAT, 0); class_addmethod(accum_class, (t_method)accum_set, gensym("set"), A_FLOAT, 0); } pd-miXedSon-0.2beta3/hammer/acos.c000066400000000000000000000022511276723360300167740ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include "m_pd.h" #if defined(_WIN32) || defined(__APPLE__) /* cf pd/src/x_arithmetic.c */ #define acosf acos #endif typedef struct _acos { t_object x_ob; float x_value; } t_acos; static t_class *acos_class; static void acos_bang(t_acos *x) { outlet_float(((t_object *)x)->ob_outlet, x->x_value); } static void acos_float(t_acos *x, t_float f) { if (f < -1.0) f = -1.0; else if (f > 1.0) f = 1.0; /* CHECKME */ outlet_float(((t_object *)x)->ob_outlet, x->x_value = acosf(f)); } static void *acos_new(t_floatarg f) { t_acos *x = (t_acos *)pd_new(acos_class); if (f < -1.0) f = -1.0; else if (f > 1.0) f = 1.0; /* CHECKME */ x->x_value = acosf(f); outlet_new((t_object *)x, &s_float); return (x); } void acos_setup(void) { acos_class = class_new(gensym("acos"), (t_newmethod)acos_new, 0, sizeof(t_acos), 0, A_DEFFLOAT, 0); class_addbang(acos_class, acos_bang); class_addfloat(acos_class, acos_float); } pd-miXedSon-0.2beta3/hammer/active.c000066400000000000000000000025501276723360300173240ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include "m_pd.h" #include "hammer/gui.h" typedef struct _active { t_object x_ob; t_symbol *x_cvname; int x_on; } t_active; static t_class *active_class; static void active_dofocus(t_active *x, t_symbol *s, t_floatarg f) { if ((int)f) { int on = (s == x->x_cvname); if (on != x->x_on) outlet_float(((t_object *)x)->ob_outlet, x->x_on = on); } else if (x->x_on && s == x->x_cvname) outlet_float(((t_object *)x)->ob_outlet, x->x_on = 0); } static void active_free(t_active *x) { hammergui_unbindfocus((t_pd *)x); } static void *active_new(void) { t_active *x = (t_active *)pd_new(active_class); char buf[32]; sprintf(buf, ".x%lx.c", (unsigned long)canvas_getcurrent()); x->x_cvname = gensym(buf); x->x_on = 0; outlet_new((t_object *)x, &s_float); hammergui_bindfocus((t_pd *)x); return (x); } void active_setup(void) { active_class = class_new(gensym("active"), (t_newmethod)active_new, (t_method)active_free, sizeof(t_active), CLASS_NOINLET, 0); class_addmethod(active_class, (t_method)active_dofocus, gensym("_focus"), A_SYMBOL, A_FLOAT, 0); } pd-miXedSon-0.2beta3/hammer/allhammers.c000066400000000000000000000072321276723360300202000ustar00rootroot00000000000000// Do not edit this file, run "make" instead. /* Copyright (c) 2002-2004 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ void Append_setup(void); void Borax_setup(void); void Bucket_setup(void); void Clip_setup(void); void Decode_setup(void); void Histo_setup(void); void MouseState_setup(void); void Peak_setup(void); void Table_setup(void); void TogEdge_setup(void); void Trough_setup(void); void Uzi_setup(void); void accum_setup(void); void acos_setup(void); void active_setup(void); void anal_setup(void); void asin_setup(void); void bangbang_setup(void); void bondo_setup(void); void buddy_setup(void); void capture_setup(void); void cartopol_setup(void); void coll_setup(void); void comment_setup(void); void cosh_setup(void); void counter_setup(void); void cycle_setup(void); void decide_setup(void); void drunk_setup(void); void flush_setup(void); void forward_setup(void); void fromsymbol_setup(void); void funbuff_setup(void); void funnel_setup(void); void gate_setup(void); void grab_setup(void); void iter_setup(void); void match_setup(void); void maximum_setup(void); void mean_setup(void); void midiflush_setup(void); void midiformat_setup(void); void midiparse_setup(void); void minimum_setup(void); void mousefilter_setup(void); void mtr_setup(void); void next_setup(void); void offer_setup(void); void onebang_setup(void); void past_setup(void); void poltocar_setup(void); void prepend_setup(void); void prob_setup(void); void pv_setup(void); void seq_setup(void); void sinh_setup(void); void speedlim_setup(void); void spell_setup(void); void split_setup(void); void spray_setup(void); void sprintf_setup(void); void substitute_setup(void); void sustain_setup(void); void switch_setup(void); void tanh_setup(void); void testmess_setup(void); void thresh_setup(void); void tosymbol_setup(void); void universal_setup(void); void urn_setup(void); void xbendin_setup(void); void xbendin2_setup(void); void xbendout_setup(void); void xbendout2_setup(void); void xnotein_setup(void); void xnoteout_setup(void); void zl_setup(void); void allhammers_setup(void) { Append_setup(); Borax_setup(); Bucket_setup(); Clip_setup(); Decode_setup(); Histo_setup(); MouseState_setup(); Peak_setup(); Table_setup(); TogEdge_setup(); Trough_setup(); Uzi_setup(); accum_setup(); acos_setup(); active_setup(); anal_setup(); asin_setup(); bangbang_setup(); bondo_setup(); buddy_setup(); capture_setup(); cartopol_setup(); coll_setup(); comment_setup(); cosh_setup(); counter_setup(); cycle_setup(); decide_setup(); drunk_setup(); flush_setup(); forward_setup(); fromsymbol_setup(); funbuff_setup(); funnel_setup(); gate_setup(); grab_setup(); iter_setup(); match_setup(); maximum_setup(); mean_setup(); midiflush_setup(); midiformat_setup(); midiparse_setup(); minimum_setup(); mousefilter_setup(); mtr_setup(); next_setup(); offer_setup(); onebang_setup(); past_setup(); poltocar_setup(); prepend_setup(); prob_setup(); pv_setup(); seq_setup(); sinh_setup(); speedlim_setup(); spell_setup(); split_setup(); spray_setup(); sprintf_setup(); substitute_setup(); sustain_setup(); switch_setup(); tanh_setup(); testmess_setup(); thresh_setup(); tosymbol_setup(); universal_setup(); urn_setup(); xbendin_setup(); xbendin2_setup(); xbendout_setup(); xbendout2_setup(); xnotein_setup(); xnoteout_setup(); zl_setup(); } pd-miXedSon-0.2beta3/hammer/anal.c000066400000000000000000000054201276723360300167630ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include "m_pd.h" #include "common/loud.h" #define ANAL_DEFSIZE 128 #define ANAL_MAXSIZE 1024 typedef struct _anal { t_object x_ob; int x_value; /* negative, if initialized or reset */ int x_size; int x_bytesize; int *x_table; /* CHECKED: the 'weight' count is a signed short (2 bytes), wrapping into negative domain without any warning. LATER consider complaining at == SHRT_MAX. */ } t_anal; static t_class *anal_class; static void anal_reset(t_anal *x) { x->x_value = -1; } static void anal_clear(t_anal *x) { memset(x->x_table, 0, x->x_bytesize); } static void anal_float(t_anal *x, t_float f) { int value; if (loud_checkint((t_pd *)x, f, &value, &s_float)) /* CHECKED */ { /* CHECKED: any input negative or >= size is ignored with an error -- there is no output, and a previous state is kept. */ if (value >= 0 && value < x->x_size) { if (x->x_value >= 0) { t_atom at[3]; int ndx = x->x_value * x->x_size + value; x->x_table[ndx]++; SETFLOAT(at, x->x_value); SETFLOAT(&at[1], value); SETFLOAT(&at[2], x->x_table[ndx]); outlet_list(((t_object *)x)->ob_outlet, &s_list, 3, at); } x->x_value = value; } else loud_error((t_pd *)x, "%d outside of table bounds", value); } } static void anal_free(t_anal *x) { if (x->x_table) freebytes(x->x_table, x->x_bytesize); } static void *anal_new(t_floatarg f) { t_anal *x; int size = (int)f; int bytesize; int *table; if (size < 1) /* CHECKED: 1 is allowed (such an object rejects any nonzero input) */ size = ANAL_DEFSIZE; else if (size > ANAL_MAXSIZE) { /* CHECKED: */ loud_warning(&anal_class, 0, "size too large, using %d", ANAL_MAXSIZE); size = ANAL_MAXSIZE; /* LATER switch into a 'sparse' mode */ } /* CHECKED: actually the bytesize is size * size * sizeof(short), and it shows up in */ bytesize = size * size * sizeof(*table); if (!(table = (int *)getbytes(bytesize))) return (0); x = (t_anal *)pd_new(anal_class); x->x_size = size; x->x_bytesize = bytesize; x->x_table = table; outlet_new((t_object *)x, &s_list); anal_reset(x); anal_clear(x); return (x); } void anal_setup(void) { anal_class = class_new(gensym("anal"), (t_newmethod)anal_new, (t_method)anal_free, sizeof(t_anal), 0, A_DEFFLOAT, 0); class_addfloat(anal_class, anal_float); class_addmethod(anal_class, (t_method)anal_reset, gensym("reset"), 0); class_addmethod(anal_class, (t_method)anal_clear, gensym("clear"), 0); } pd-miXedSon-0.2beta3/hammer/asin.c000066400000000000000000000022511276723360300170010ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include "m_pd.h" #if defined(_WIN32) || defined(__APPLE__) /* cf pd/src/x_arithmetic.c */ #define asinf asin #endif typedef struct _asin { t_object x_ob; float x_value; } t_asin; static t_class *asin_class; static void asin_bang(t_asin *x) { outlet_float(((t_object *)x)->ob_outlet, x->x_value); } static void asin_float(t_asin *x, t_float f) { if (f < -1.0) f = -1.0; else if (f > 1.0) f = 1.0; /* CHECKME */ outlet_float(((t_object *)x)->ob_outlet, x->x_value = asinf(f)); } static void *asin_new(t_floatarg f) { t_asin *x = (t_asin *)pd_new(asin_class); if (f < -1.0) f = -1.0; else if (f > 1.0) f = 1.0; /* CHECKME */ x->x_value = asinf(f); outlet_new((t_object *)x, &s_float); return (x); } void asin_setup(void) { asin_class = class_new(gensym("asin"), (t_newmethod)asin_new, 0, sizeof(t_asin), 0, A_DEFFLOAT, 0); class_addbang(asin_class, asin_bang); class_addfloat(asin_class, asin_float); } pd-miXedSon-0.2beta3/hammer/bangbang.c000066400000000000000000000040341276723360300176070ustar00rootroot00000000000000/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* This is a modified version of Joseph A. Sarlo's code. The most important changes are listed in "pd-lib-notes.txt" file. */ #include "m_pd.h" #include "common/loud.h" #include "common/fitter.h" #define BANGBANG_MINOUTS 1 #define BANGBANG_C74MAXOUTS 40 /* CHECKED (just clipped without warning) */ #define BANGBANG_DEFOUTS 2 typedef struct _bangbang { t_object x_ob; int x_nouts; t_outlet **x_outs; t_outlet *x_outbuf[BANGBANG_DEFOUTS]; } t_bangbang; static t_class *bangbang_class; static void bangbang_bang(t_bangbang *x) { int i = x->x_nouts; while (i--) outlet_bang(x->x_outs[i]); } static void bangbang_anything(t_bangbang *x, t_symbol *s, int ac, t_atom *av) { bangbang_bang(x); } static void bangbang_free(t_bangbang *x) { if (x->x_outs != x->x_outbuf) freebytes(x->x_outs, x->x_nouts * sizeof(*x->x_outs)); } static void *bangbang_new(t_floatarg val) { t_bangbang *x; int i, nouts = (int)val; t_outlet **outs; if (nouts < BANGBANG_MINOUTS) nouts = BANGBANG_DEFOUTS; if (nouts > BANGBANG_C74MAXOUTS) fittermax_rangewarning(bangbang_class, BANGBANG_C74MAXOUTS, "outlets"); if (nouts > BANGBANG_DEFOUTS) { if (!(outs = (t_outlet **)getbytes(nouts * sizeof(*outs)))) return (0); } else outs = 0; x = (t_bangbang *)pd_new(bangbang_class); x->x_nouts = nouts; x->x_outs = (outs ? outs : x->x_outbuf); for (i = 0; i < nouts; i++) x->x_outs[i] = outlet_new((t_object *)x, &s_bang); return (x); } void bangbang_setup(void) { bangbang_class = class_new(gensym("bangbang"), (t_newmethod)bangbang_new, (t_method)bangbang_free, sizeof(t_bangbang), 0, A_DEFFLOAT, 0); class_addbang(bangbang_class, bangbang_bang); class_addanything(bangbang_class, bangbang_anything); fitter_setup(bangbang_class, 0); } pd-miXedSon-0.2beta3/hammer/bondo.c000066400000000000000000000255001276723360300171520ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* LATER revisit buffer handling (maxsize, reentrancy) */ /* LATER rethink handling of symbols */ /* CHECKED: if 'n' argument is given, then store whole messages, instead of distributing atoms across successive slots. This is a new, buddy-like behaviour. */ /* CHECKED: without 'n' argument, 'symbol test' is parsed as two symbol atoms, but 'float 1' (or 'list 1') as a single float. */ #include #include "m_pd.h" #include "common/grow.h" #define BONDO_MINSLOTS 2 #define BONDO_INISIZE 4 /* LATER rethink (useful only in multiatom mode) */ typedef struct _bondo { t_object x_ob; t_float x_delay; int x_multiatom; int x_nslots; int x_nproxies; /* as requested (and allocated) */ t_pd **x_proxies; t_outlet **x_outs; t_clock *x_clock; } t_bondo; typedef struct _bondo_proxy { t_object p_ob; t_bondo *p_master; int p_id; t_symbol *p_selector; t_float p_float; t_symbol *p_symbol; t_gpointer *p_pointer; int p_size; /* as allocated */ int p_natoms; /* as used */ t_atom *p_message; t_atom p_messini[BONDO_INISIZE]; } t_bondo_proxy; static t_class *bondo_class; static t_class *bondo_proxy_class; static void bondo_doit(t_bondo *x) { t_bondo_proxy **p = (t_bondo_proxy **)x->x_proxies; int i = x->x_nslots; p = (t_bondo_proxy **)x->x_proxies; i = x->x_nslots; while (i--) { t_symbol *s = p[i]->p_selector; /* LATER consider complaining about extra arguments (CHECKED) */ if (s == &s_bang) outlet_bang(x->x_outs[i]); else if (s == &s_float) outlet_float(x->x_outs[i], p[i]->p_float); else if (s == &s_symbol && p[i]->p_symbol) { /* LATER rethink */ if (x->x_multiatom) outlet_symbol(x->x_outs[i], p[i]->p_symbol); else outlet_anything(x->x_outs[i], p[i]->p_symbol, 0, 0); } else if (s == &s_pointer) { /* LATER */ } else if (s == &s_list) outlet_list(x->x_outs[i], s, p[i]->p_natoms, p[i]->p_message); else if (s) /* CHECKED: a slot may be inactive (in multiatom mode) */ outlet_anything(x->x_outs[i], s, p[i]->p_natoms, p[i]->p_message); } } static void bondo_arm(t_bondo *x) { if (x->x_delay <= 0) bondo_doit(x); else clock_delay(x->x_clock, x->x_delay); } static void bondo_proxy_bang(t_bondo_proxy *x) { bondo_arm(x->p_master); /* CHECKED: bang in any inlet works in this way */ } static void bondo_proxy_dofloat(t_bondo_proxy *x, t_float f, int doit) { x->p_selector = &s_float; x->p_float = f; x->p_natoms = 0; /* defensive */ if (doit) bondo_arm(x->p_master); } static void bondo_proxy_float(t_bondo_proxy *x, t_float f) { bondo_proxy_dofloat(x, f, 1); } static void bondo_proxy_dosymbol(t_bondo_proxy *x, t_symbol *s, int doit) { x->p_selector = &s_symbol; x->p_symbol = s; x->p_natoms = 0; /* defensive */ if (doit) bondo_arm(x->p_master); } static void bondo_proxy_symbol(t_bondo_proxy *x, t_symbol *s) { bondo_proxy_dosymbol(x, s, 1); } static void bondo_proxy_dopointer(t_bondo_proxy *x, t_gpointer *gp, int doit) { x->p_selector = &s_pointer; x->p_pointer = gp; x->p_natoms = 0; /* defensive */ if (doit) bondo_arm(x->p_master); } static void bondo_proxy_pointer(t_bondo_proxy *x, t_gpointer *gp) { bondo_proxy_dopointer(x, gp, 1); } /* CHECKED: the slots fire in right-to-left order, but they trigger only once (refman error) */ static void bondo_distribute(t_bondo *x, int startid, t_symbol *s, int ac, t_atom *av, int doit) { t_atom *ap = av; t_bondo_proxy **pp; int id = startid + ac; if (s) id++; if (id > x->x_nslots) id = x->x_nslots; ap += id - startid; pp = (t_bondo_proxy **)(x->x_proxies + id); if (s) ap--; while (ap-- > av) { pp--; if (ap->a_type == A_FLOAT) bondo_proxy_dofloat(*pp, ap->a_w.w_float, 0); else if (ap->a_type == A_SYMBOL) bondo_proxy_dosymbol(*pp, ap->a_w.w_symbol, 0); else if (ap->a_type == A_POINTER) bondo_proxy_dopointer(*pp, ap->a_w.w_gpointer, 0); } if (s) bondo_proxy_dosymbol((t_bondo_proxy *)x->x_proxies[startid], s, 0); if (doit) bondo_arm(x); } static void bondo_proxy_domultiatom(t_bondo_proxy *x, int ac, t_atom *av, int doit) { if (ac > x->p_size) { /* LATER consider using BONDO_MAXSIZE (and warning if exceeded) */ x->p_message = grow_nodata(&ac, &x->p_size, x->p_message, BONDO_INISIZE, x->p_messini, sizeof(*x->p_message)); } x->p_natoms = ac; memcpy(x->p_message, av, ac * sizeof(*x->p_message)); if (doit) bondo_arm(x->p_master); } static void bondo_proxy_dolist(t_bondo_proxy *x, int ac, t_atom *av, int doit) { if (x->p_master->x_multiatom) { x->p_selector = &s_list; bondo_proxy_domultiatom(x, ac, av, doit); } else bondo_distribute(x->p_master, x->p_id, 0, ac, av, doit); } static void bondo_proxy_list(t_bondo_proxy *x, t_symbol *s, int ac, t_atom *av) { bondo_proxy_dolist(x, ac, av, 1); } static void bondo_proxy_doanything(t_bondo_proxy *x, t_symbol *s, int ac, t_atom *av, int doit) { if (x->p_master->x_multiatom) { /* LATER rethink and CHECKME */ if (s == &s_symbol) { if (ac && av->a_type == A_SYMBOL) bondo_proxy_dosymbol(x, av->a_w.w_symbol, doit); else bondo_proxy_dosymbol(x, &s_symbol, doit); } else { x->p_selector = s; bondo_proxy_domultiatom(x, ac, av, doit); } } else bondo_distribute(x->p_master, x->p_id, s, ac, av, doit); } static void bondo_proxy_anything(t_bondo_proxy *x, t_symbol *s, int ac, t_atom *av) { bondo_proxy_doanything(x, s, ac, av, 1); } static void bondo_proxy_set(t_bondo_proxy *x, t_symbol *s, int ac, t_atom *av) { if (ac) { if (av->a_type == A_FLOAT) { if (ac > 1) bondo_proxy_dolist(x, ac, av, 0); else bondo_proxy_dofloat(x, av->a_w.w_float, 0); } else if (av->a_type == A_SYMBOL) /* CHECKED: no tests for 'set float ...' and 'set list...' -- the parsing is made in an output routine */ bondo_proxy_doanything(x, av->a_w.w_symbol, ac-1, av+1, 0); else if (av->a_type == A_POINTER) bondo_proxy_dopointer(x, av->a_w.w_gpointer, 0); } /* CHECKED: 'set' without arguments makes a slot inactive, if multiatom, but is ignored, if !multiatom */ else if (x->p_master->x_multiatom) x->p_selector = 0; } static void bondo_bang(t_bondo *x) { bondo_proxy_bang((t_bondo_proxy *)x->x_proxies[0]); } static void bondo_float(t_bondo *x, t_float f) { bondo_proxy_dofloat((t_bondo_proxy *)x->x_proxies[0], f, 1); } static void bondo_symbol(t_bondo *x, t_symbol *s) { bondo_proxy_dosymbol((t_bondo_proxy *)x->x_proxies[0], s, 1); } static void bondo_pointer(t_bondo *x, t_gpointer *gp) { bondo_proxy_dopointer((t_bondo_proxy *)x->x_proxies[0], gp, 1); } static void bondo_list(t_bondo *x, t_symbol *s, int ac, t_atom *av) { bondo_proxy_dolist((t_bondo_proxy *)x->x_proxies[0], ac, av, 1); } static void bondo_anything(t_bondo *x, t_symbol *s, int ac, t_atom *av) { bondo_proxy_doanything((t_bondo_proxy *)x->x_proxies[0], s, ac, av, 1); } static void bondo_set(t_bondo *x, t_symbol *s, int ac, t_atom *av) { bondo_proxy_set((t_bondo_proxy *)x->x_proxies[0], s, ac, av); } static void bondo_free(t_bondo *x) { if (x->x_clock) clock_free(x->x_clock); if (x->x_proxies) { int i = x->x_nslots; while (i--) { t_bondo_proxy *y = (t_bondo_proxy *)x->x_proxies[i]; if (y->p_message != y->p_messini) freebytes(y->p_message, y->p_size * sizeof(*y->p_message)); pd_free((t_pd *)y); } freebytes(x->x_proxies, x->x_nproxies * sizeof(*x->x_proxies)); } if (x->x_outs) freebytes(x->x_outs, x->x_nslots * sizeof(*x->x_outs)); } static void *bondo_new(t_symbol *s, int ac, t_atom *av) { t_bondo *x; int i, nslots, nproxies = BONDO_MINSLOTS; int multiatom = 0; t_float delay = 0; t_pd **proxies; t_outlet **outs; i = 0; while (ac--) { /* CHECKED: no warnings */ if (av->a_type == A_FLOAT) { if (i == 0) nproxies = (int)av->a_w.w_float; else if (i == 1) delay = av->a_w.w_float; i++; } else if (av->a_type == A_SYMBOL) { if (av->a_w.w_symbol == gensym("n")) multiatom = 1; /* CHECKED: 'n' has to be the last argument given; the arguments after any symbol are silently ignored -- LATER decide if we should comply and break here */ } av++; } if (nproxies < BONDO_MINSLOTS) nproxies = BONDO_MINSLOTS; if (!(proxies = (t_pd **)getbytes(nproxies * sizeof(*proxies)))) return (0); for (nslots = 0; nslots < nproxies; nslots++) if (!(proxies[nslots] = pd_new(bondo_proxy_class))) break; if (nslots < BONDO_MINSLOTS || !(outs = (t_outlet **)getbytes(nslots * sizeof(*outs)))) { i = nslots; while (i--) pd_free(proxies[i]); freebytes(proxies, nproxies * sizeof(*proxies)); return (0); } x = (t_bondo *)pd_new(bondo_class); x->x_delay = delay; x->x_multiatom = multiatom; x->x_nslots = nslots; x->x_nproxies = nproxies; x->x_proxies = proxies; x->x_outs = outs; for (i = 0; i < nslots; i++) { t_bondo_proxy *y = (t_bondo_proxy *)proxies[i]; y->p_master = x; y->p_id = i; y->p_selector = &s_float; /* CHECKED: it is so in multiatom mode too */ y->p_float = 0; y->p_symbol = 0; y->p_pointer = 0; y->p_size = BONDO_INISIZE; y->p_natoms = 0; y->p_message = y->p_messini; if (i) inlet_new((t_object *)x, (t_pd *)y, 0, 0); x->x_outs[i] = outlet_new((t_object *)x, &s_anything); } x->x_clock = clock_new(x, (t_method)bondo_doit); return (x); } void bondo_setup(void) { bondo_class = class_new(gensym("bondo"), (t_newmethod)bondo_new, (t_method)bondo_free, sizeof(t_bondo), 0, A_GIMME, 0); class_addbang(bondo_class, bondo_bang); class_addfloat(bondo_class, bondo_float); class_addsymbol(bondo_class, bondo_symbol); class_addpointer(bondo_class, bondo_pointer); class_addlist(bondo_class, bondo_list); class_addanything(bondo_class, bondo_anything); class_addmethod(bondo_class, (t_method)bondo_set, gensym("set"), A_GIMME, 0); bondo_proxy_class = class_new(gensym("_bondo_proxy"), 0, 0, sizeof(t_bondo_proxy), CLASS_PD | CLASS_NOINLET, 0); class_addbang(bondo_proxy_class, bondo_proxy_bang); class_addfloat(bondo_proxy_class, bondo_proxy_float); class_addsymbol(bondo_proxy_class, bondo_proxy_symbol); class_addpointer(bondo_proxy_class, bondo_proxy_pointer); class_addlist(bondo_proxy_class, bondo_proxy_list); class_addanything(bondo_proxy_class, bondo_proxy_anything); class_addmethod(bondo_proxy_class, (t_method)bondo_proxy_set, gensym("set"), A_GIMME, 0); } pd-miXedSon-0.2beta3/hammer/buddy.c000066400000000000000000000153261276723360300171650ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* LATER compare with buddy.c from max sdk */ /* LATER revisit buffer handling (maxsize, reentrancy) */ #include #include "m_pd.h" #include "common/grow.h" #define BUDDY_MINSLOTS 2 #define BUDDY_INISIZE 4 /* LATER rethink */ typedef struct _buddy { t_object x_ob; int x_nslots; int x_nproxies; /* as requested (and allocated) */ t_pd **x_proxies; t_outlet **x_outs; } t_buddy; typedef struct _buddy_proxy { t_object p_ob; t_buddy *p_master; t_symbol *p_selector; t_float p_float; t_symbol *p_symbol; t_gpointer *p_pointer; int p_size; /* as allocated */ int p_natoms; /* as used */ t_atom *p_message; t_atom p_messini[BUDDY_INISIZE]; } t_buddy_proxy; static t_class *buddy_class; static t_class *buddy_proxy_class; static void buddy_clear(t_buddy *x) { t_buddy_proxy **p = (t_buddy_proxy **)x->x_proxies; int i = x->x_nslots; while (i--) { (*p)->p_selector = 0; (*p++)->p_natoms = 0; /* defensive */ } } static void buddy_check(t_buddy *x) { t_buddy_proxy **p = (t_buddy_proxy **)x->x_proxies; int i = x->x_nslots; while (i--) if (!(*p++)->p_selector) return; p = (t_buddy_proxy **)x->x_proxies; i = x->x_nslots; while (i--) { t_symbol *s = p[i]->p_selector; if (s == &s_bang) outlet_bang(x->x_outs[i]); else if (s == &s_float) outlet_float(x->x_outs[i], p[i]->p_float); else if (s == &s_symbol && p[i]->p_symbol) outlet_symbol(x->x_outs[i], p[i]->p_symbol); else if (s == &s_pointer) { /* LATER */ } else if (s == &s_list) outlet_list(x->x_outs[i], s, p[i]->p_natoms, p[i]->p_message); else if (s) outlet_anything(x->x_outs[i], s, p[i]->p_natoms, p[i]->p_message); } buddy_clear(x); } static void buddy_proxy_bang(t_buddy_proxy *x) { x->p_selector = &s_bang; x->p_natoms = 0; /* defensive */ buddy_check(x->p_master); } static void buddy_proxy_float(t_buddy_proxy *x, t_float f) { x->p_selector = &s_float; x->p_float = f; x->p_natoms = 0; /* defensive */ buddy_check(x->p_master); } static void buddy_proxy_symbol(t_buddy_proxy *x, t_symbol *s) { x->p_selector = &s_symbol; x->p_symbol = s; x->p_natoms = 0; /* defensive */ buddy_check(x->p_master); } static void buddy_proxy_pointer(t_buddy_proxy *x, t_gpointer *gp) { x->p_selector = &s_pointer; x->p_pointer = gp; x->p_natoms = 0; /* defensive */ buddy_check(x->p_master); } static void buddy_proxy_domessage(t_buddy_proxy *x, int ac, t_atom *av) { if (ac > x->p_size) { /* LATER consider using BUDDY_MAXSIZE (and warning if exceeded) */ x->p_message = grow_nodata(&ac, &x->p_size, x->p_message, BUDDY_INISIZE, x->p_messini, sizeof(*x->p_message)); } x->p_natoms = ac; memcpy(x->p_message, av, ac * sizeof(*x->p_message)); buddy_check(x->p_master); } static void buddy_proxy_list(t_buddy_proxy *x, t_symbol *s, int ac, t_atom *av) { x->p_selector = &s_list; /* LATER rethink */ buddy_proxy_domessage(x, ac, av); } static void buddy_proxy_anything(t_buddy_proxy *x, t_symbol *s, int ac, t_atom *av) { x->p_selector = s; /* LATER rethink */ buddy_proxy_domessage(x, ac, av); } static void buddy_bang(t_buddy *x) { buddy_proxy_bang((t_buddy_proxy *)x->x_proxies[0]); } static void buddy_float(t_buddy *x, t_float f) { buddy_proxy_float((t_buddy_proxy *)x->x_proxies[0], f); } static void buddy_symbol(t_buddy *x, t_symbol *s) { buddy_proxy_symbol((t_buddy_proxy *)x->x_proxies[0], s); } static void buddy_pointer(t_buddy *x, t_gpointer *gp) { buddy_proxy_pointer((t_buddy_proxy *)x->x_proxies[0], gp); } static void buddy_list(t_buddy *x, t_symbol *s, int ac, t_atom *av) { buddy_proxy_list((t_buddy_proxy *)x->x_proxies[0], s, ac, av); } static void buddy_anything(t_buddy *x, t_symbol *s, int ac, t_atom *av) { buddy_proxy_anything((t_buddy_proxy *)x->x_proxies[0], s, ac, av); } static void buddy_free(t_buddy *x) { if (x->x_proxies) { int i = x->x_nslots; while (i--) { t_buddy_proxy *y = (t_buddy_proxy *)x->x_proxies[i]; if (y->p_message != y->p_messini) freebytes(y->p_message, y->p_size * sizeof(*y->p_message)); pd_free((t_pd *)y); } freebytes(x->x_proxies, x->x_nproxies * sizeof(*x->x_proxies)); } if (x->x_outs) freebytes(x->x_outs, x->x_nslots * sizeof(*x->x_outs)); } static void *buddy_new(t_floatarg f) { t_buddy *x; int i, nslots, nproxies = (int)f; t_pd **proxies; t_outlet **outs; if (nproxies < BUDDY_MINSLOTS) nproxies = BUDDY_MINSLOTS; if (!(proxies = (t_pd **)getbytes(nproxies * sizeof(*proxies)))) return (0); for (nslots = 0; nslots < nproxies; nslots++) if (!(proxies[nslots] = pd_new(buddy_proxy_class))) break; if (nslots < BUDDY_MINSLOTS || !(outs = (t_outlet **)getbytes(nslots * sizeof(*outs)))) { int i = nslots; while (i--) pd_free(proxies[i]); freebytes(proxies, nproxies * sizeof(*proxies)); return (0); } x = (t_buddy *)pd_new(buddy_class); x->x_nslots = nslots; x->x_nproxies = nproxies; x->x_proxies = proxies; x->x_outs = outs; for (i = 0; i < nslots; i++) { t_buddy_proxy *y = (t_buddy_proxy *)proxies[i]; y->p_master = x; y->p_selector = 0; y->p_float = 0; y->p_symbol = 0; y->p_pointer = 0; y->p_size = BUDDY_INISIZE; y->p_natoms = 0; y->p_message = y->p_messini; if (i) inlet_new((t_object *)x, (t_pd *)y, 0, 0); x->x_outs[i] = outlet_new((t_object *)x, &s_anything); } return (x); } void buddy_setup(void) { buddy_class = class_new(gensym("buddy"), (t_newmethod)buddy_new, (t_method)buddy_free, sizeof(t_buddy), 0, A_DEFFLOAT, 0); class_addbang(buddy_class, buddy_bang); class_addfloat(buddy_class, buddy_float); class_addsymbol(buddy_class, buddy_symbol); class_addpointer(buddy_class, buddy_pointer); class_addlist(buddy_class, buddy_list); class_addanything(buddy_class, buddy_anything); class_addmethod(buddy_class, (t_method)buddy_clear, gensym("clear"), 0); buddy_proxy_class = class_new(gensym("_buddy_proxy"), 0, 0, sizeof(t_buddy_proxy), CLASS_PD | CLASS_NOINLET, 0); class_addbang(buddy_proxy_class, buddy_proxy_bang); class_addfloat(buddy_proxy_class, buddy_proxy_float); class_addsymbol(buddy_proxy_class, buddy_proxy_symbol); class_addpointer(buddy_proxy_class, buddy_proxy_pointer); class_addlist(buddy_proxy_class, buddy_proxy_list); class_addanything(buddy_proxy_class, buddy_proxy_anything); } pd-miXedSon-0.2beta3/hammer/capture.c000066400000000000000000000164001276723360300175130ustar00rootroot00000000000000/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include "m_pd.h" #include "common/loud.h" #include "hammer/file.h" #define CAPTURE_DEFSIZE 512 typedef struct _capture { t_object x_ob; t_canvas *x_canvas; char x_intmode; /* if nonzero ('x' or 'm') floats are ignored */ float *x_buffer; int x_bufsize; int x_count; int x_head; t_hammerfile *x_filehandle; } t_capture; static t_class *capture_class; static void capture_float(t_capture *x, t_float f) { if (x->x_intmode && f != (int)f) /* CHECKME float */ return; x->x_buffer[x->x_head++] = f; if (x->x_head >= x->x_bufsize) x->x_head = 0; if (x->x_count < x->x_bufsize) x->x_count++; } static void capture_list(t_capture *x, t_symbol *s, int ac, t_atom *av) { while (ac--) { if (av->a_type == A_FLOAT) /* CHECKME */ capture_float(x, av->a_w.w_float); av++; } } static void capture_clear(t_capture *x) { x->x_count = 0; x->x_head = 0; } static void capture_count(t_capture *x) { post("capture: %d items received", /* CHECKED */ x->x_count); /* CHECKED incompatible (4.07 seems buggy here) */ } static void capture_dump(t_capture *x) { int count = x->x_count; if (count < x->x_bufsize) { float *bp = x->x_buffer; while (count--) outlet_float(((t_object *)x)->ob_outlet, *bp++); } else { float *bp = x->x_buffer + x->x_head; count = x->x_bufsize - x->x_head; while (count--) outlet_float(((t_object *)x)->ob_outlet, *bp++); bp = x->x_buffer; count = x->x_head; while (count--) outlet_float(((t_object *)x)->ob_outlet, *bp++); } } static int capture_formatint(int i, char *buf, int col, int maxcol, char *fmt) { char *bp = buf; int cnt = 0; if (col > 0) *bp++ = ' ', cnt++; cnt += sprintf(bp, fmt, i); if (col + cnt > maxcol) buf[0] = '\n', col = cnt - 1; /* assuming col > 0 */ else col += cnt; return (col); } static int capture_formatfloat(float f, char *buf, int col, int maxcol, char *fmt) { char *bp = buf; int cnt = 0; if (col > 0) *bp++ = ' ', cnt++; cnt += sprintf(bp, fmt, f); if (col + cnt > maxcol) buf[0] = '\n', col = cnt - 1; /* assuming col > 0 */ else col += cnt; return (col); } static int capture_formatnumber(t_capture *x, float f, char *buf, int col, int maxcol) { char intmode = x->x_intmode; if (intmode == 'm') intmode = (f < 128 && f > -128 ? 'd' : 'x'); /* CHECKME */ if (intmode == 'x') col = capture_formatint((int)f, buf, col, maxcol, "%x"); else if (intmode) col = capture_formatint((int)f, buf, col, maxcol, "%d"); else col = capture_formatfloat(f, buf, col, maxcol, "%g"); return (col); } static int capture_writefloat(t_capture *x, float f, char *buf, int col, FILE *fp) { /* CHECKED no linebreaks (FIXME) */ col = capture_formatnumber(x, f, buf, col, 80); return (fputs(buf, fp) < 0 ? -1 : col); } static void capture_dowrite(t_capture *x, t_symbol *fn) { FILE *fp = 0; int count = x->x_count; char buf[MAXPDSTRING]; canvas_makefilename(x->x_canvas, fn->s_name, buf, MAXPDSTRING); if (fp = sys_fopen(buf, "w")) /* LATER ask if overwriting, CHECKED */ { int col = 0; if (count < x->x_bufsize) { float *bp = x->x_buffer; while (count--) if ((col = capture_writefloat(x, *bp++, buf, col, fp)) < 0) goto fail; } else { float *bp = x->x_buffer + x->x_head; count = x->x_bufsize - x->x_head; while (count--) if ((col = capture_writefloat(x, *bp++, buf, col, fp)) < 0) goto fail; bp = x->x_buffer; count = x->x_head; while (count--) if ((col = capture_writefloat(x, *bp++, buf, col, fp)) < 0) goto fail; } if (col) fputc('\n', fp); fclose(fp); return; } fail: if (fp) fclose(fp); loud_syserror((t_pd *)x, 0); } static void capture_writehook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { capture_dowrite((t_capture *)z, fn); } static void capture_write(t_capture *x, t_symbol *s) { if (s && s != &s_) capture_dowrite(x, s); else hammerpanel_save(x->x_filehandle, 0, 0); } static int capture_appendfloat(t_capture *x, float f, char *buf, int col) { /* CHECKED 80 columns */ col = capture_formatnumber(x, f, buf, col, 80); hammereditor_append(x->x_filehandle, buf); return (col); } static void capture_open(t_capture *x) { int count = x->x_count; char buf[MAXPDSTRING]; hammereditor_open(x->x_filehandle, "Capture", ""); /* CHECKED */ if (count < x->x_bufsize) { float *bp = x->x_buffer; int col = 0; while (count--) col = capture_appendfloat(x, *bp++, buf, col); } else { float *bp = x->x_buffer + x->x_head; int col = 0; count = x->x_bufsize - x->x_head; while (count--) col = capture_appendfloat(x, *bp++, buf, col); bp = x->x_buffer; count = x->x_head; while (count--) col = capture_appendfloat(x, *bp++, buf, col); } } /* CHECKED without asking and storing the changes */ static void capture_wclose(t_capture *x) { hammereditor_close(x->x_filehandle, 0); } static void capture_click(t_capture *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) { capture_open(x); } static void capture_free(t_capture *x) { hammerfile_free(x->x_filehandle); if (x->x_buffer) freebytes(x->x_buffer, x->x_bufsize * sizeof(*x->x_buffer)); } static void *capture_new(t_symbol *s, t_floatarg f) { t_capture *x = 0; float *buffer; int bufsize = (int)f; /* CHECKME */ if (bufsize <= 0) /* CHECKME */ bufsize = CAPTURE_DEFSIZE; if (buffer = getbytes(bufsize * sizeof(*buffer))) { x = (t_capture *)pd_new(capture_class); x->x_canvas = canvas_getcurrent(); if (s && s != &s_) { if (s == gensym("x")) x->x_intmode = 'x'; else if (s == gensym("m")) x->x_intmode = 'm'; else x->x_intmode = 'd'; /* ignore floats */ } x->x_buffer = buffer; x->x_bufsize = bufsize; outlet_new((t_object *)x, &s_float); x->x_filehandle = hammerfile_new((t_pd *)x, 0, 0, capture_writehook, 0); capture_clear(x); } return (x); } void capture_setup(void) { capture_class = class_new(gensym("capture"), (t_newmethod)capture_new, (t_method)capture_free, sizeof(t_capture), 0, A_DEFFLOAT, A_DEFSYM, 0); class_addfloat(capture_class, capture_float); class_addlist(capture_class, capture_list); class_addmethod(capture_class, (t_method)capture_clear, gensym("clear"), 0); class_addmethod(capture_class, (t_method)capture_count, gensym("count"), 0); class_addmethod(capture_class, (t_method)capture_dump, gensym("dump"), 0); class_addmethod(capture_class, (t_method)capture_write, gensym("write"), A_DEFSYM, 0); class_addmethod(capture_class, (t_method)capture_open, gensym("open"), 0); class_addmethod(capture_class, (t_method)capture_wclose, gensym("wclose"), 0); class_addmethod(capture_class, (t_method)capture_click, gensym("click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); hammerfile_setup(capture_class, 0); } pd-miXedSon-0.2beta3/hammer/cartopol.c000066400000000000000000000021621276723360300176730ustar00rootroot00000000000000/* Copyright (c) 2002-2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include "m_pd.h" #if defined(_WIN32) || defined(__APPLE__) /* cf pd/src/x_arithmetic.c */ #define atan2f atan2 #define hypotf hypot #endif typedef struct _cartopol { t_object x_ob; t_float x_imag; t_outlet *x_out2; } t_cartopol; static t_class *cartopol_class; static void cartopol_float(t_cartopol *x, t_float f) { outlet_float(x->x_out2, atan2f(x->x_imag, f)); outlet_float(((t_object *)x)->ob_outlet, hypotf(f, x->x_imag)); } static void *cartopol_new(void) { t_cartopol *x = (t_cartopol *)pd_new(cartopol_class); floatinlet_new((t_object *)x, &x->x_imag); outlet_new((t_object *)x, &s_float); x->x_out2 = outlet_new((t_object *)x, &s_float); return (x); } void cartopol_setup(void) { cartopol_class = class_new(gensym("cartopol"), (t_newmethod)cartopol_new, 0, sizeof(t_cartopol), 0, 0); class_addfloat(cartopol_class, cartopol_float); } pd-miXedSon-0.2beta3/hammer/coll.c000066400000000000000000001230021276723360300167760ustar00rootroot00000000000000/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #include #include #include "m_pd.h" #include "g_canvas.h" #include "common/loud.h" #include "hammer/file.h" /* LATER profile for the bottlenecks of insertion and sorting */ /* LATER make sure that ``reentrancy protection hack'' is really working... */ #ifdef KRZYSZCZ //#define COLL_DEBUG #endif enum { COLL_HEADRESET, COLL_HEADNEXT, COLL_HEADPREV, /* distinction not used, currently */ COLL_HEADDELETED }; typedef struct _collelem { int e_hasnumkey; int e_numkey; t_symbol *e_symkey; struct _collelem *e_prev; struct _collelem *e_next; int e_size; t_atom *e_data; } t_collelem; typedef struct _collcommon { t_pd c_pd; struct _coll *c_refs; /* used in read-banging and dirty flag handling */ int c_increation; int c_volatile; int c_selfmodified; int c_entered; /* a counter, LATER rethink */ int c_embedflag; /* common field (CHECKED in 'TEXT' files) */ t_symbol *c_filename; /* CHECKED common for all, read and write */ t_canvas *c_lastcanvas; t_hammerfile *c_filehandle; t_collelem *c_first; t_collelem *c_last; t_collelem *c_head; int c_headstate; } t_collcommon; typedef struct _coll { t_object x_ob; t_canvas *x_canvas; t_symbol *x_name; t_collcommon *x_common; t_hammerfile *x_filehandle; t_outlet *x_keyout; t_outlet *x_filebangout; t_outlet *x_dumpbangout; struct _coll *x_next; } t_coll; static t_class *coll_class; static t_class *collcommon_class; static t_collelem *collelem_new(int ac, t_atom *av, int *np, t_symbol *s) { t_collelem *ep = (t_collelem *)getbytes(sizeof(*ep)); if (ep->e_hasnumkey = (np != 0)) ep->e_numkey = *np; ep->e_symkey = s; ep->e_prev = ep->e_next = 0; if (ep->e_size = ac) { t_atom *ap = getbytes(ac * sizeof(*ap)); ep->e_data = ap; if (av) while (ac--) *ap++ = *av++; else while (ac--) { SETFLOAT(ap, 0); ap++; } } else ep->e_data = 0; return (ep); } static void collelem_free(t_collelem *ep) { if (ep->e_data) freebytes(ep->e_data, ep->e_size * sizeof(*ep->e_data)); freebytes(ep, sizeof(*ep)); } /* CHECKME again... apparently c74 is not able to fix this for good */ /* result: 1 for ep1 < ep2, 0 for ep1 >= ep2, all symbols are < any float */ static int collelem_less(t_collelem *ep1, t_collelem *ep2, int ndx, int swap) { int isless; if (swap) { t_collelem *ep = ep1; ep1 = ep2; ep2 = ep; } if (ndx < 0) { if (ep1->e_symkey) isless = (ep2->e_symkey ? strcmp(ep1->e_symkey->s_name, ep2->e_symkey->s_name) < 0 : 1); /* CHECKED incompatible with 4.07, but consistent */ else if (ep2->e_symkey) isless = 0; /* CHECKED incompatible with 4.07, but consistent */ else isless = (ep1->e_numkey < ep2->e_numkey); /* CHECKED in 4.07 */ } else { t_atom *ap1 = (ndx < ep1->e_size ? ep1->e_data + ndx : ep1->e_data + ep1->e_size - 1); t_atom *ap2 = (ndx < ep2->e_size ? ep2->e_data + ndx : ep2->e_data + ep2->e_size - 1); if (ap1->a_type == A_FLOAT) { if (ap2->a_type == A_FLOAT) isless = (ap1->a_w.w_float < ap2->a_w.w_float); else if (ap2->a_type == A_SYMBOL) isless = 0; else isless = 1; } else if (ap1->a_type == A_SYMBOL) { if (ap2->a_type == A_FLOAT) isless = 1; else if (ap2->a_type == A_SYMBOL) isless = (strcmp(ap1->a_w.w_symbol->s_name, ap2->a_w.w_symbol->s_name) < 0); else isless = 1; } else isless = 0; } return (isless); } static t_collelem *collcommon_numkey(t_collcommon *cc, int numkey) { t_collelem *ep; for (ep = cc->c_first; ep; ep = ep->e_next) if (ep->e_hasnumkey && ep->e_numkey == numkey) return (ep); return (0); } static t_collelem *collcommon_symkey(t_collcommon *cc, t_symbol *symkey) { t_collelem *ep; for (ep = cc->c_first; ep; ep = ep->e_next) if (ep->e_symkey == symkey) return (ep); return (0); } static void collcommon_takeout(t_collcommon *cc, t_collelem *ep) { if (ep->e_prev) ep->e_prev->e_next = ep->e_next; else cc->c_first = ep->e_next; if (ep->e_next) ep->e_next->e_prev = ep->e_prev; else cc->c_last = ep->e_prev; if (cc->c_head == ep) { cc->c_head = ep->e_next; /* asymmetric, LATER rethink */ cc->c_headstate = COLL_HEADDELETED; } } static void collcommon_modified(t_collcommon *cc, int relinked) { if (cc->c_increation) return; if (relinked) { cc->c_volatile = 1; } if (cc->c_embedflag) { t_coll *x; for (x = cc->c_refs; x; x = x->x_next) if (x->x_canvas && glist_isvisible(x->x_canvas)) canvas_dirty(x->x_canvas, 1); } } /* atomic collcommon modifiers: clearall, remove, replace, putbefore, putafter, swaplinks, swapkeys, changesymkey, renumber, sort */ static void collcommon_clearall(t_collcommon *cc) { if (cc->c_first) { t_collelem *ep1 = cc->c_first, *ep2; do { ep2 = ep1->e_next; collelem_free(ep1); } while (ep1 = ep2); cc->c_first = cc->c_last = 0; cc->c_head = 0; cc->c_headstate = COLL_HEADRESET; collcommon_modified(cc, 1); } } static void collcommon_remove(t_collcommon *cc, t_collelem *ep) { collcommon_takeout(cc, ep); collelem_free(ep); collcommon_modified(cc, 1); } static void collcommon_replace(t_collcommon *cc, t_collelem *ep, int ac, t_atom *av, int *np, t_symbol *s) { if (ep->e_hasnumkey = (np != 0)) ep->e_numkey = *np; ep->e_symkey = s; if (ac) { int i = ac; t_atom *ap; if (ep->e_data) { if (ep->e_size != ac) ap = resizebytes(ep->e_data, ep->e_size * sizeof(*ap), ac * sizeof(*ap)); else ap = ep->e_data; } else ap = getbytes(ac * sizeof(*ap)); ep->e_data = ap; if (av) while (i --) *ap++ = *av++; else while (i --) { SETFLOAT(ap, 0); ap++; } } else { if (ep->e_data) freebytes(ep->e_data, ep->e_size * sizeof(*ep->e_data)); ep->e_data = 0; } ep->e_size = ac; collcommon_modified(cc, 0); } static void collcommon_putbefore(t_collcommon *cc, t_collelem *ep, t_collelem *next) { if (next) { ep->e_next = next; if (ep->e_prev = next->e_prev) ep->e_prev->e_next = ep; else cc->c_first = ep; next->e_prev = ep; } else if (cc->c_first || cc->c_last) loudbug_bug("collcommon_putbefore"); else cc->c_first = cc->c_last = ep; collcommon_modified(cc, 1); } static void collcommon_putafter(t_collcommon *cc, t_collelem *ep, t_collelem *prev) { if (prev) { ep->e_prev = prev; if (ep->e_next = prev->e_next) ep->e_next->e_prev = ep; else cc->c_last = ep; prev->e_next = ep; } else if (cc->c_first || cc->c_last) loudbug_bug("collcommon_putafter"); else cc->c_first = cc->c_last = ep; collcommon_modified(cc, 1); } /* LATER consider making it faster, if there is a real need. Now called only in the sort routine, once per sort. */ static void collcommon_swaplinks(t_collcommon *cc, t_collelem *ep1, t_collelem *ep2) { if (ep1 != ep2) { t_collelem *prev1 = ep1->e_prev, *prev2 = ep2->e_prev; if (prev1 == ep2) { collcommon_takeout(cc, ep2); collcommon_putafter(cc, ep2, ep1); } else if (prev2 == ep1) { collcommon_takeout(cc, ep1); collcommon_putafter(cc, ep1, ep2); } else if (prev1) { if (prev2) { collcommon_takeout(cc, ep1); collcommon_takeout(cc, ep2); collcommon_putafter(cc, ep1, prev2); collcommon_putafter(cc, ep2, prev1); } else { t_collelem *next2 = ep2->e_next; collcommon_takeout(cc, ep1); collcommon_takeout(cc, ep2); collcommon_putbefore(cc, ep1, next2); collcommon_putafter(cc, ep2, prev1); } } else if (prev2) { t_collelem *next1 = ep1->e_next; collcommon_takeout(cc, ep1); collcommon_takeout(cc, ep2); collcommon_putafter(cc, ep1, prev2); collcommon_putbefore(cc, ep2, next1); } else loudbug_bug("collcommon_swaplinks"); } } static void collcommon_swapkeys(t_collcommon *cc, t_collelem *ep1, t_collelem *ep2) { int hasnumkey = ep2->e_hasnumkey, numkey = ep2->e_numkey; t_symbol *symkey = ep2->e_symkey; ep2->e_hasnumkey = ep1->e_hasnumkey; ep2->e_numkey = ep1->e_numkey; ep2->e_symkey = ep1->e_symkey; ep1->e_hasnumkey = hasnumkey; ep1->e_numkey = numkey; ep1->e_symkey = symkey; collcommon_modified(cc, 0); } static void collcommon_changesymkey(t_collcommon *cc, t_collelem *ep, t_symbol *s) { ep->e_symkey = s; collcommon_modified(cc, 0); } static void collcommon_renumber(t_collcommon *cc, int startkey) { t_collelem *ep; for (ep = cc->c_first; ep; ep = ep->e_next) if (ep->e_hasnumkey) ep->e_numkey = startkey++; collcommon_modified(cc, 0); } /* LATER choose a better algo, after coll's storage structures stabilize. Note, that even the simple insertion sort below (n-square) might prove better for bi-directional lists, than theoretically efficient algo (nlogn) requiring random access emulation. Avoiding recursion is not a bad idea, too. */ static void collcommon_sort(t_collcommon *cc, int descending, int ndx) { t_collelem *min = cc->c_first; t_collelem *ep; if (min && (ep = min->e_next)) { cc->c_increation = 1; /* search for a sentinel element */ do if (collelem_less(ep, min, ndx, descending)) min = ep; while (ep = ep->e_next); /* prepend it */ collcommon_swaplinks(cc, cc->c_first, min); /* sort */ ep = min->e_next->e_next; while (ep) { t_collelem *next = ep->e_next; for (min = ep->e_prev; min && /* LATER remove */ collelem_less(ep, min, ndx, descending); min = min->e_prev); if (!min) /* LATER remove */ loudbug_bug("collcommon_sort"); else if (ep != min->e_next) { collcommon_takeout(cc, ep); collcommon_putafter(cc, ep, min); } ep = next; } cc->c_increation = 0; collcommon_modified(cc, 1); } } static void collcommon_adddata(t_collcommon *cc, t_collelem *ep, int ac, t_atom *av) { if (ac) { t_atom *ap; int newsize = ep->e_size + ac; if (ep->e_data) ap = resizebytes(ep->e_data, ep->e_size * sizeof(*ap), newsize * sizeof(*ap)); else { ep->e_size = 0; /* redundant, hopefully */ ap = getbytes(newsize * sizeof(*ap)); } ep->e_data = ap; ap += ep->e_size; if (av) while (ac--) *ap++ = *av++; else while (ac--) { SETFLOAT(ap, 0); ap++; } ep->e_size = newsize; collcommon_modified(cc, 0); } } static t_collelem *collcommon_tonumkey(t_collcommon *cc, int numkey, int ac, t_atom *av, int replace) { t_collelem *old = collcommon_numkey(cc, numkey), *new; if (old && replace) collcommon_replace(cc, new = old, ac, av, &numkey, 0); else { new = collelem_new(ac, av, &numkey, 0); if (old) { collcommon_putbefore(cc, new, old); do if (old->e_hasnumkey) /* CHECKED incremented up to the last one; incompatible: elements with numkey == 0 not incremented (a bug?) */ old->e_numkey++; while (old = old->e_next); } else { /* CHECKED negative numkey always put before the last element, zero numkey always becomes the new head */ int closestkey = 0; t_collelem *closest = 0, *ep; for (ep = cc->c_first; ep; ep = ep->e_next) { if (ep->e_hasnumkey) { if (numkey >= closestkey && numkey <= ep->e_numkey) { collcommon_putbefore(cc, new, ep); break; } closestkey = ep->e_numkey; } closest = ep; } if (!ep) { if (numkey <= closestkey) collcommon_putbefore(cc, new, closest); else collcommon_putafter(cc, new, closest); } } } return (new); } static t_collelem *collcommon_tosymkey(t_collcommon *cc, t_symbol *symkey, int ac, t_atom *av, int replace) { t_collelem *old = collcommon_symkey(cc, symkey), *new; if (old && replace) collcommon_replace(cc, new = old, ac, av, 0, symkey); else collcommon_putafter(cc, new = collelem_new(ac, av, 0, symkey), cc->c_last); return (new); } static int collcommon_fromatoms(t_collcommon *cc, int ac, t_atom *av) { int hasnumkey = 0, numkey; t_symbol *symkey = 0; int size = 0; t_atom *data = 0; int nlines = 0; cc->c_increation = 1; collcommon_clearall(cc); while (ac--) { if (data) { if (av->a_type == A_SEMI) { t_collelem *ep = collelem_new(size, data, hasnumkey ? &numkey : 0, symkey); collcommon_putafter(cc, ep, cc->c_last); hasnumkey = 0; symkey = 0; data = 0; nlines++; } if (av->a_type == A_COMMA) { /* CHECKED rejecting a comma */ collcommon_clearall(cc); /* LATER rethink */ cc->c_increation = 0; return (-nlines); } else size++; } else if (av->a_type == A_COMMA) { size = 0; data = av + 1; } else if (av->a_type == A_SYMBOL) symkey = av->a_w.w_symbol; else if (av->a_type == A_FLOAT && loud_checkint(0, av->a_w.w_float, &numkey, 0)) hasnumkey = 1; else { loud_error(0, "coll: bad atom"); collcommon_clearall(cc); /* LATER rethink */ cc->c_increation = 0; return (-nlines); } av++; } if (data) { loud_error(0, "coll: incomplete"); collcommon_clearall(cc); /* LATER rethink */ cc->c_increation = 0; return (-nlines); } cc->c_increation = 0; return (nlines); } static int collcommon_frombinbuf(t_collcommon *cc, t_binbuf *bb) { return (collcommon_fromatoms(cc, binbuf_getnatom(bb), binbuf_getvec(bb))); } static void collcommon_doread(t_collcommon *cc, t_symbol *fn, t_canvas *cv) { t_binbuf *bb; char buf[MAXPDSTRING]; if (!fn && !(fn = cc->c_filename)) /* !fn: 'readagain' */ return; /* FIXME use open_via_path() */ if (cv || (cv = cc->c_lastcanvas)) /* !cv: 'read' w/o arg, 'readagain' */ canvas_makefilename(cv, fn->s_name, buf, MAXPDSTRING); else { strncpy(buf, fn->s_name, MAXPDSTRING); buf[MAXPDSTRING-1] = 0; } if (!cc->c_refs) { /* loading during object creation -- avoid binbuf_read()'s complaints, LATER rethink */ FILE *fp; if (!(fp = sys_fopen(buf, "r"))) { loud_warning(&coll_class, 0, "no coll file '%s'", buf); return; } fclose(fp); } bb = binbuf_new(); if (binbuf_read(bb, buf, "", 0)) loud_error(0, "coll: error reading text file '%s'", fn->s_name); else { int nlines = collcommon_frombinbuf(cc, bb); if (nlines > 0) { t_coll *x; /* LATER consider making this more robust */ for (x = cc->c_refs; x; x = x->x_next) outlet_bang(x->x_filebangout); cc->c_lastcanvas = cv; cc->c_filename = fn; post("coll: finished reading %d lines from text file '%s'", nlines, fn->s_name); } else if (nlines < 0) loud_error(0, "coll: error in line %d of text file '%s'", 1 - nlines, fn->s_name); else loud_error(0, "coll: error reading text file '%s'", fn->s_name); if (cc->c_refs) collcommon_modified(cc, 1); } binbuf_free(bb); } static void collcommon_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { collcommon_doread((t_collcommon *)z, fn, 0); } static void collcommon_tobinbuf(t_collcommon *cc, t_binbuf *bb) { t_collelem *ep; t_atom at[3]; for (ep = cc->c_first; ep; ep = ep->e_next) { t_atom *ap = at; int cnt = 1; if (ep->e_hasnumkey) { SETFLOAT(ap, ep->e_numkey); ap++; cnt++; } if (ep->e_symkey) { SETSYMBOL(ap, ep->e_symkey); ap++; cnt++; } SETCOMMA(ap); binbuf_add(bb, cnt, at); binbuf_add(bb, ep->e_size, ep->e_data); binbuf_addsemi(bb); } } static void collcommon_dowrite(t_collcommon *cc, t_symbol *fn, t_canvas *cv) { t_binbuf *bb; int ac; t_atom *av; char buf[MAXPDSTRING]; if (!fn && !(fn = cc->c_filename)) /* !fn: 'writeagain' */ return; if (cv || (cv = cc->c_lastcanvas)) /* !cv: 'write' w/o arg, 'writeagain' */ canvas_makefilename(cv, fn->s_name, buf, MAXPDSTRING); else { strncpy(buf, fn->s_name, MAXPDSTRING); buf[MAXPDSTRING-1] = 0; } bb = binbuf_new(); collcommon_tobinbuf(cc, bb); if (binbuf_write(bb, buf, "", 0)) loud_error(0, "coll: error writing text file '%s'", fn->s_name); else { cc->c_lastcanvas = cv; cc->c_filename = fn; } binbuf_free(bb); } static void collcommon_writehook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { collcommon_dowrite((t_collcommon *)z, fn, 0); } static void coll_embedhook(t_pd *z, t_binbuf *bb, t_symbol *bindsym) { t_coll *x = (t_coll *)z; t_collcommon *cc = x->x_common; if (cc->c_embedflag) { t_collelem *ep; t_atom at[6]; binbuf_addv(bb, "ssii;", bindsym, gensym("flags"), 1, 0); SETSYMBOL(at, bindsym); for (ep = cc->c_first; ep; ep = ep->e_next) { t_atom *ap = at + 1; int cnt; if (ep->e_hasnumkey && ep->e_symkey) { SETSYMBOL(ap, gensym("nstore")); ap++; SETSYMBOL(ap, ep->e_symkey); ap++; SETFLOAT(ap, ep->e_numkey); cnt = 4; } else if (ep->e_symkey) { SETSYMBOL(ap, gensym("store")); ap++; SETSYMBOL(ap, ep->e_symkey); cnt = 3; } else { SETFLOAT(ap, ep->e_numkey); cnt = 2; } binbuf_add(bb, cnt, at); binbuf_add(bb, ep->e_size, ep->e_data); binbuf_addsemi(bb); } } } static void collcommon_editorhook(t_pd *z, t_symbol *s, int ac, t_atom *av) { int nlines = collcommon_fromatoms((t_collcommon *)z, ac, av); if (nlines < 0) loud_error(0, "coll: editing error in line %d", 1 - nlines); } static void collcommon_free(t_collcommon *cc) { t_collelem *ep1, *ep2 = cc->c_first; while (ep1 = ep2) { ep2 = ep1->e_next; collelem_free(ep1); } } static void *collcommon_new(void) { t_collcommon *cc = (t_collcommon *)pd_new(collcommon_class); cc->c_embedflag = 0; cc->c_first = cc->c_last = 0; cc->c_head = 0; cc->c_headstate = COLL_HEADRESET; return (cc); } static t_collcommon *coll_checkcommon(t_coll *x) { if (x->x_name && x->x_common != (t_collcommon *)pd_findbyclass(x->x_name, collcommon_class)) { loudbug_bug("coll_checkcommon"); return (0); } return (x->x_common); } static void coll_unbind(t_coll *x) { /* LATER consider calling coll_checkcommon(x) */ t_collcommon *cc = x->x_common; t_coll *prev, *next; if ((prev = cc->c_refs) == x) { if (!(cc->c_refs = x->x_next)) { hammerfile_free(cc->c_filehandle); collcommon_free(cc); if (x->x_name) pd_unbind(&cc->c_pd, x->x_name); pd_free(&cc->c_pd); } } else if (prev) { while (next = prev->x_next) { if (next == x) { prev->x_next = next->x_next; break; } prev = next; } } x->x_common = 0; x->x_name = 0; x->x_next = 0; } static void coll_bind(t_coll *x, t_symbol *name) { t_collcommon *cc = 0; if (name == &s_) name = 0; else if (name) cc = (t_collcommon *)pd_findbyclass(name, collcommon_class); if (!cc) { cc = (t_collcommon *)collcommon_new(); cc->c_refs = 0; cc->c_increation = 0; if (name) { pd_bind(&cc->c_pd, name); /* LATER rethink canvas unpredictability */ collcommon_doread(cc, name, x->x_canvas); } else { cc->c_filename = 0; cc->c_lastcanvas = 0; } cc->c_filehandle = hammerfile_new((t_pd *)cc, 0, collcommon_readhook, collcommon_writehook, collcommon_editorhook); } x->x_common = cc; x->x_name = name; x->x_next = cc->c_refs; cc->c_refs = x; } static int coll_rebind(t_coll *x, t_symbol *name) { t_collcommon *cc; if (name && name != &s_ && (cc = (t_collcommon *)pd_findbyclass(name, collcommon_class))) { coll_unbind(x); x->x_common = cc; x->x_name = name; x->x_next = cc->c_refs; cc->c_refs = x; return (1); } else return (0); } static void coll_dooutput(t_coll *x, int ac, t_atom *av) { if (ac > 1) { if (av->a_type == A_FLOAT) outlet_list(((t_object *)x)->ob_outlet, &s_list, ac, av); else if (av->a_type == A_SYMBOL) outlet_anything(((t_object *)x)->ob_outlet, av->a_w.w_symbol, ac-1, av+1); } else if (ac) { if (av->a_type == A_FLOAT) outlet_float(((t_object *)x)->ob_outlet, av->a_w.w_float); else if (av->a_type == A_SYMBOL) outlet_symbol(((t_object *)x)->ob_outlet, av->a_w.w_symbol); } } static void coll_keyoutput(t_coll *x, t_collelem *ep) { t_collcommon *cc = x->x_common; if (!cc->c_entered++) cc->c_selfmodified = 0; cc->c_volatile = 0; if (ep->e_hasnumkey) outlet_float(x->x_keyout, ep->e_numkey); else if (ep->e_symkey) outlet_symbol(x->x_keyout, ep->e_symkey); else outlet_float(x->x_keyout, 0); if (cc->c_volatile) cc->c_selfmodified = 1; cc->c_entered--; } static t_collelem *coll_findkey(t_coll *x, t_atom *key, t_symbol *mess) { t_collcommon *cc = x->x_common; t_collelem *ep = 0; if (key->a_type == A_FLOAT) { int numkey; if (loud_checkint((t_pd *)x, key->a_w.w_float, &numkey, mess)) ep = collcommon_numkey(cc, numkey); else mess = 0; } else if (key->a_type == A_SYMBOL) ep = collcommon_symkey(cc, key->a_w.w_symbol); else if (mess) { loud_messarg((t_pd *)x, mess); mess = 0; } if (!ep && mess) loud_error((t_pd *)x, "no such key"); return (ep); } static t_collelem *coll_tokey(t_coll *x, t_atom *key, int ac, t_atom *av, int replace, t_symbol *mess) { t_collcommon *cc = x->x_common; t_collelem *ep = 0; if (key->a_type == A_FLOAT) { int numkey; if (loud_checkint((t_pd *)x, key->a_w.w_float, &numkey, mess)) ep = collcommon_tonumkey(cc, numkey, ac, av, replace); } else if (key->a_type == A_SYMBOL) ep = collcommon_tosymkey(cc, key->a_w.w_symbol, ac, av, replace); else if (mess) loud_messarg((t_pd *)x, mess); return (ep); } static t_collelem *coll_firsttyped(t_coll *x, int ndx, t_atomtype type) { t_collcommon *cc = x->x_common; t_collelem *ep; for (ep = cc->c_first; ep; ep = ep->e_next) if (ep->e_size > ndx && ep->e_data[ndx].a_type == type) return (ep); return (0); } /* the methods */ static void coll_float(t_coll *x, t_float f) { t_collcommon *cc = x->x_common; t_collelem *ep; int numkey; if (loud_checkint((t_pd *)x, f, &numkey, &s_float) && (ep = collcommon_numkey(cc, numkey))) { coll_keyoutput(x, ep); if (!cc->c_selfmodified || (ep = collcommon_numkey(cc, numkey))) coll_dooutput(x, ep->e_size, ep->e_data); } } static void coll_symbol(t_coll *x, t_symbol *s) { t_collcommon *cc = x->x_common; t_collelem *ep; if (ep = collcommon_symkey(cc, s)) { coll_keyoutput(x, ep); if (!cc->c_selfmodified || (ep = collcommon_symkey(cc, s))) coll_dooutput(x, ep->e_size, ep->e_data); } } static void coll_list(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac >= 2 && av->a_type == A_FLOAT) coll_tokey(x, av, ac-1, av+1, 1, &s_list); else loud_messarg((t_pd *)x, &s_list); } static void coll_anything(t_coll *x, t_symbol *s, int ac, t_atom *av) { coll_symbol(x, s); } static void coll_store(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac >= 2) coll_tokey(x, av, ac-1, av+1, 1, s); else loud_messarg((t_pd *)x, s); } static void coll_nstore(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac >= 3) { t_collcommon *cc = x->x_common; t_collelem *ep; int numkey; if (av->a_type == A_FLOAT && av[1].a_type == A_SYMBOL) { if (loud_checkint((t_pd *)x, av->a_w.w_float, &numkey, s)) { if (ep = collcommon_symkey(cc, av[1].a_w.w_symbol)) collcommon_remove(cc, ep); ep = collcommon_tonumkey(cc, numkey, ac-2, av+2, 1); ep->e_symkey = av[1].a_w.w_symbol; } } else if (av->a_type == A_SYMBOL && av[1].a_type == A_FLOAT) { if (loud_checkint((t_pd *)x, av[1].a_w.w_float, &numkey, s)) { if (ep = collcommon_numkey(cc, numkey)) collcommon_remove(cc, ep); ep = collcommon_tosymkey(cc, av->a_w.w_symbol, ac-2, av+2, 1); ep->e_hasnumkey = 1; ep->e_numkey = numkey; } } else loud_messarg((t_pd *)x, s); } else loud_messarg((t_pd *)x, s); } static void coll_insert(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac >= 2 && av->a_type == A_FLOAT) coll_tokey(x, av, ac-1, av+1, 0, s); else loud_messarg((t_pd *)x, s); } static void coll_remove(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac) { t_collelem *ep; if (ep = coll_findkey(x, av, s)) collcommon_remove(x->x_common, ep); } else loud_messarg((t_pd *)x, s); } static void coll_delete(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac) { t_collelem *ep; if (ep = coll_findkey(x, av, s)) { if (av->a_type == A_FLOAT) { int numkey = ep->e_numkey; t_collelem *next; for (next = ep->e_next; next; next = next->e_next) if (next->e_hasnumkey && next->e_numkey > numkey) next->e_numkey--; } collcommon_remove(x->x_common, ep); } } else loud_messarg((t_pd *)x, s); } static void coll_assoc(t_coll *x, t_symbol *s, t_floatarg f) { int numkey; if (loud_checkint((t_pd *)x, f, &numkey, gensym("assoc"))) { t_collcommon *cc = x->x_common; t_collelem *ep1, *ep2; if ((ep1 = collcommon_numkey(cc, numkey)) && ep1->e_symkey != s) /* LATER rethink */ { if (ep2 = collcommon_symkey(cc, s)) collcommon_remove(cc, ep2); collcommon_changesymkey(cc, ep1, s); } } } static void coll_deassoc(t_coll *x, t_symbol *s, t_floatarg f) { int numkey; if (loud_checkint((t_pd *)x, f, &numkey, gensym("deassoc"))) { t_collcommon *cc = x->x_common; t_collelem *ep; if (ep = collcommon_numkey(cc, numkey)) collcommon_changesymkey(cc, ep, 0); } } static void coll_subsym(t_coll *x, t_symbol *s1, t_symbol *s2) { t_collelem *ep; if (s1 != s2 && (ep = collcommon_symkey(x->x_common, s2))) collcommon_changesymkey(x->x_common, ep, s1); } static void coll_renumber(t_coll *x, t_floatarg f) { int startkey; if (loud_checkint((t_pd *)x, f, &startkey, gensym("renumber"))) collcommon_renumber(x->x_common, startkey); } static void coll_merge(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac >= 2) { t_collcommon *cc = x->x_common; t_collelem *ep; if (av->a_type == A_FLOAT) { int numkey; if (loud_checkint((t_pd *)x, av->a_w.w_float, &numkey, s)) { if (ep = collcommon_numkey(cc, numkey)) collcommon_adddata(cc, ep, ac-1, av+1); else /* LATER consider defining collcommon_toclosest() */ collcommon_tonumkey(cc, numkey, ac-1, av+1, 1); } } else if (av->a_type == A_SYMBOL) { if (ep = collcommon_symkey(cc, av->a_w.w_symbol)) collcommon_adddata(cc, ep, ac-1, av+1); else { ep = collelem_new(ac-1, av+1, 0, av->a_w.w_symbol); collcommon_putafter(cc, ep, cc->c_last); } } else loud_messarg((t_pd *)x, s); } else loud_messarg((t_pd *)x, s); } static void coll_sub(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac) { t_collelem *ep; if (ep = coll_findkey(x, av, s)) { t_collcommon *cc = x->x_common; t_atom *key = av++; ac--; while (ac >= 2) { if (av->a_type == A_FLOAT) { int ndx; if (loud_checkint((t_pd *)x, av->a_w.w_float, &ndx, 0) && ndx >= 1 && ndx <= ep->e_size) ep->e_data[ndx-1] = av[1]; } ac -= 2; av += 2; } if (s == gensym("sub")) { coll_keyoutput(x, ep); if (!cc->c_selfmodified || (ep = coll_findkey(x, key, 0))) coll_dooutput(x, ep->e_size, ep->e_data); } } } else loud_messarg((t_pd *)x, s); } static void coll_sort(t_coll *x, t_floatarg f1, t_floatarg f2) { int dir, ndx; if (loud_checkint((t_pd *)x, f1, &dir, gensym("sort")) && loud_checkint((t_pd *)x, f2, &ndx, gensym("sort"))) collcommon_sort(x->x_common, (dir < 0 ? 0 : 1), (ndx < 0 ? -1 : (ndx ? ndx - 1 : 0))); } static void coll_clear(t_coll *x) { collcommon_clearall(x->x_common); } /* According to the refman, the data should be swapped, rather than the keys -- easy here, but apparently c74 people have chosen to avoid some effort needed in case of their implementation... */ static void coll_swap(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac == 2) { t_collelem *ep1, *ep2; if ((ep1 = coll_findkey(x, av, s)) && (ep2 = coll_findkey(x, av + 1, s))) collcommon_swapkeys(x->x_common, ep1, ep2); } else loud_messarg((t_pd *)x, s); } /* CHECKED traversal direction change is consistent with the general rule: 'next' always outputs e_next of a previous output, and 'prev' always outputs e_prev, whether preceded by 'prev', or by 'next'. This is currently implemented by pre-updating of the head (which is inhibited if there was no previous output, i.e. after 'goto', 'end', or collection initialization). CHECKME again. */ static void coll_next(t_coll *x) { t_collcommon *cc = x->x_common; if (cc->c_headstate != COLL_HEADRESET && cc->c_headstate != COLL_HEADDELETED) /* asymmetric, LATER rethink */ { if (cc->c_head) cc->c_head = cc->c_head->e_next; if (!cc->c_head && !(cc->c_head = cc->c_first)) /* CHECKED wrapping */ return; } else if (!cc->c_head && !(cc->c_head = cc->c_first)) return; cc->c_headstate = COLL_HEADNEXT; coll_keyoutput(x, cc->c_head); if (cc->c_head) coll_dooutput(x, cc->c_head->e_size, cc->c_head->e_data); else if (!cc->c_selfmodified) loudbug_bug("coll_next"); /* LATER rethink */ } static void coll_prev(t_coll *x) { t_collcommon *cc = x->x_common; if (cc->c_headstate != COLL_HEADRESET) { if (cc->c_head) cc->c_head = cc->c_head->e_prev; if (!cc->c_head && !(cc->c_head = cc->c_last)) /* CHECKED wrapping */ return; } else if (!cc->c_head && !(cc->c_head = cc->c_first)) return; cc->c_headstate = COLL_HEADPREV; coll_keyoutput(x, cc->c_head); if (cc->c_head) coll_dooutput(x, cc->c_head->e_size, cc->c_head->e_data); else if (!cc->c_selfmodified) loudbug_bug("coll_prev"); /* LATER rethink */ } static void coll_start(t_coll *x) { t_collcommon *cc = x->x_common; cc->c_head = cc->c_first; cc->c_headstate = COLL_HEADRESET; } static void coll_end(t_coll *x) { t_collcommon *cc = x->x_common; cc->c_head = cc->c_last; cc->c_headstate = COLL_HEADRESET; } static void coll_goto(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac) { t_collelem *ep = coll_findkey(x, av, s); if (ep) { t_collcommon *cc = x->x_common; cc->c_head = ep; cc->c_headstate = COLL_HEADRESET; } } else coll_start(x); //loud_messarg((t_pd *)x, s); } static void coll_nth(t_coll *x, t_symbol *s, int ac, t_atom *av) { if (ac >= 2 && av[1].a_type == A_FLOAT) { int ndx; t_collelem *ep; if (loud_checkint((t_pd *)x, av[1].a_w.w_float, &ndx, s) && (ep = coll_findkey(x, av, s)) && ep->e_size >= ndx) { t_atom *ap = ep->e_data + --ndx; if (ap->a_type == A_FLOAT) outlet_float(((t_object *)x)->ob_outlet, ap->a_w.w_float); else if (ap->a_type == A_SYMBOL) outlet_symbol(((t_object *)x)->ob_outlet, ap->a_w.w_symbol); } } else loud_messarg((t_pd *)x, s); } static void coll_length(t_coll *x) { t_collcommon *cc = x->x_common; t_collelem *ep = cc->c_first; int result = 0; while (ep) result++, ep = ep->e_next; outlet_float(((t_object *)x)->ob_outlet, result); } static void coll_min(t_coll *x, t_floatarg f) { int ndx; if (loud_checkint((t_pd *)x, f, &ndx, gensym("min"))) { t_collelem *found; if (ndx > 0) ndx--; /* LATER consider complaining: */ else if (ndx < 0) return; /* CHECKED silently rejected */ /* else CHECKED silently defaults to 1 */ if (found = coll_firsttyped(x, ndx, A_FLOAT)) { t_float result = found->e_data[ndx].a_w.w_float; t_collelem *ep; for (ep = found->e_next; ep; ep = ep->e_next) { if (ep->e_size > ndx && ep->e_data[ndx].a_type == A_FLOAT && ep->e_data[ndx].a_w.w_float < result) { found = ep; result = ep->e_data[ndx].a_w.w_float; } } coll_keyoutput(x, found); outlet_float(((t_object *)x)->ob_outlet, result); } } } static void coll_max(t_coll *x, t_floatarg f) { int ndx; if (loud_checkint((t_pd *)x, f, &ndx, gensym("max"))) { t_collelem *found; if (ndx > 0) ndx--; /* LATER consider complaining: */ else if (ndx < 0) return; /* CHECKED silently rejected */ /* else CHECKED silently defaults to 1 */ if (found = coll_firsttyped(x, ndx, A_FLOAT)) { t_float result = found->e_data[ndx].a_w.w_float; t_collelem *ep; for (ep = found->e_next; ep; ep = ep->e_next) { if (ep->e_size > ndx && ep->e_data[ndx].a_type == A_FLOAT && ep->e_data[ndx].a_w.w_float > result) { found = ep; result = ep->e_data[ndx].a_w.w_float; } } coll_keyoutput(x, found); outlet_float(((t_object *)x)->ob_outlet, result); } } } static void coll_refer(t_coll *x, t_symbol *s) { if (!coll_rebind(x, s)) { /* LATER consider complaining */ } } static void coll_flags(t_coll *x, t_float f1, t_float f2) { int i1; if (loud_checkint((t_pd *)x, f1, &i1, gensym("flags"))) { t_collcommon *cc = x->x_common; cc->c_embedflag = (i1 != 0); } } static void coll_read(t_coll *x, t_symbol *s) { t_collcommon *cc = x->x_common; if (s && s != &s_) collcommon_doread(cc, s, x->x_canvas); else hammerpanel_open(cc->c_filehandle, 0); } static void coll_write(t_coll *x, t_symbol *s) { t_collcommon *cc = x->x_common; if (s && s != &s_) collcommon_dowrite(cc, s, x->x_canvas); else hammerpanel_save(cc->c_filehandle, 0, 0); /* CHECKED no default name */ } static void coll_readagain(t_coll *x) { t_collcommon *cc = x->x_common; if (cc->c_filename) collcommon_doread(cc, 0, 0); else hammerpanel_open(cc->c_filehandle, 0); } static void coll_writeagain(t_coll *x) { t_collcommon *cc = x->x_common; if (cc->c_filename) collcommon_dowrite(cc, 0, 0); else hammerpanel_save(cc->c_filehandle, 0, 0); /* CHECKED no default name */ } static void coll_filetype(t_coll *x, t_symbol *s) { /* dummy */ } static void coll_dump(t_coll *x) { t_collcommon *cc = x->x_common; t_collelem *ep; for (ep = cc->c_first; ep; ep = ep->e_next) { coll_keyoutput(x, ep); if (cc->c_selfmodified) break; coll_dooutput(x, ep->e_size, ep->e_data); /* FIXME dooutput() may invalidate ep as well as keyoutput()... */ } outlet_bang(x->x_dumpbangout); } static void coll_open(t_coll *x) { t_collcommon *cc = x->x_common; t_binbuf *bb = binbuf_new(); int i, natoms, newline; t_atom *ap; char buf[MAXPDSTRING]; hammereditor_open(cc->c_filehandle, (x->x_name ? x->x_name->s_name : "Untitled"), "coll"); collcommon_tobinbuf(cc, bb); natoms = binbuf_getnatom(bb); ap = binbuf_getvec(bb); newline = 1; while (natoms--) { char *ptr = buf; if (ap->a_type != A_SEMI && ap->a_type != A_COMMA && !newline) *ptr++ = ' '; atom_string(ap, ptr, MAXPDSTRING); if (ap->a_type == A_SEMI) { strcat(buf, "\n"); newline = 1; } else newline = 0; hammereditor_append(cc->c_filehandle, buf); ap++; } hammereditor_setdirty(cc->c_filehandle, 0); binbuf_free(bb); } /* CHECKED if there was any editing, both close window and 'wclose' ask and replace the contents. LATER debug. */ static void coll_wclose(t_coll *x) { hammereditor_close(x->x_common->c_filehandle, 1); } static void coll_click(t_coll *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) { coll_open(x); } #ifdef COLL_DEBUG static void collelem_post(t_collelem *ep) { if (ep->e_hasnumkey && ep->e_symkey) loudbug_startpost("%d %s:", ep->e_numkey, ep->e_symkey->s_name); else if (ep->e_hasnumkey) loudbug_startpost("%d:", ep->e_numkey); else if (ep->e_symkey) loudbug_startpost("%s:", ep->e_symkey->s_name); else loudbug_bug("collcommon_post"); loudbug_postatom(ep->e_size, ep->e_data); loudbug_endpost(); } static void collcommon_post(t_collcommon *cc) { t_collelem *ep; for (ep = cc->c_first; ep; ep = ep->e_next) collelem_post(ep); } static void coll_debug(t_coll *x, t_floatarg f) { t_collcommon *cc = coll_checkcommon(x); if (cc) { t_coll *x1 = cc->c_refs; t_collelem *ep, *last; int i = 0; while (x1) i++, x1 = x1->x_next; loudbug_post("refcount %d", i); for (ep = cc->c_first, last = 0; ep; ep = ep->e_next) last = ep; if (last != cc->c_last) loudbug_bug("coll_debug: last element"); collcommon_post(cc); } } #endif static void coll_separate(t_coll *x, t_floatarg f) { int indx; t_collcommon *cc = x->x_common; if (loud_checkint((t_pd *)x, f, &indx, gensym("separate"))) { t_collelem *ep; for (ep = cc->c_first; ep; ep = ep->e_next) if (ep->e_hasnumkey && ep->e_numkey >= indx) ep->e_numkey += 1; collcommon_modified(cc, 0); } } static void coll_free(t_coll *x) { hammerfile_free(x->x_filehandle); coll_unbind(x); } static void *coll_new(t_symbol *s) { t_coll *x = (t_coll *)pd_new(coll_class); x->x_canvas = canvas_getcurrent(); outlet_new((t_object *)x, &s_); x->x_keyout = outlet_new((t_object *)x, &s_); x->x_filebangout = outlet_new((t_object *)x, &s_bang); x->x_dumpbangout = outlet_new((t_object *)x, &s_bang); x->x_filehandle = hammerfile_new((t_pd *)x, coll_embedhook, 0, 0, 0); coll_bind(x, s); return (x); } void coll_setup(void) { coll_class = class_new(gensym("coll"), (t_newmethod)coll_new, (t_method)coll_free, sizeof(t_coll), 0, A_DEFSYM, 0); class_addbang(coll_class, coll_next); class_addfloat(coll_class, coll_float); class_addsymbol(coll_class, coll_symbol); class_addlist(coll_class, coll_list); class_addanything(coll_class, coll_anything); class_addmethod(coll_class, (t_method)coll_store, gensym("store"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_nstore, gensym("nstore"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_insert, gensym("insert"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_remove, gensym("remove"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_delete, gensym("delete"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_assoc, gensym("assoc"), A_SYMBOL, A_FLOAT, 0); class_addmethod(coll_class, (t_method)coll_deassoc, gensym("deassoc"), A_SYMBOL, A_FLOAT, 0); class_addmethod(coll_class, (t_method)coll_subsym, gensym("subsym"), A_SYMBOL, A_SYMBOL, 0); class_addmethod(coll_class, (t_method)coll_renumber, gensym("renumber"), A_DEFFLOAT, 0); class_addmethod(coll_class, (t_method)coll_merge, gensym("merge"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_sub, gensym("sub"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_sub, gensym("nsub"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_clear, gensym("clear"), 0); class_addmethod(coll_class, (t_method)coll_sort, gensym("sort"), A_FLOAT, A_DEFFLOAT, 0); class_addmethod(coll_class, (t_method)coll_swap, gensym("swap"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_next, gensym("next"), 0); class_addmethod(coll_class, (t_method)coll_prev, gensym("prev"), 0); class_addmethod(coll_class, (t_method)coll_end, gensym("end"), 0); class_addmethod(coll_class, (t_method)coll_start, gensym("start"), 0); class_addmethod(coll_class, (t_method)coll_goto, gensym("goto"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_nth, gensym("nth"), A_GIMME, 0); class_addmethod(coll_class, (t_method)coll_length, gensym("length"), 0); class_addmethod(coll_class, (t_method)coll_min, gensym("min"), A_DEFFLOAT, 0); class_addmethod(coll_class, (t_method)coll_max, gensym("max"), A_DEFFLOAT, 0); class_addmethod(coll_class, (t_method)coll_refer, gensym("refer"), A_SYMBOL, 0); class_addmethod(coll_class, (t_method)coll_flags, gensym("flags"), A_FLOAT, A_FLOAT, 0); class_addmethod(coll_class, (t_method)coll_read, gensym("read"), A_DEFSYM, 0); class_addmethod(coll_class, (t_method)coll_write, gensym("write"), A_DEFSYM, 0); class_addmethod(coll_class, (t_method)coll_readagain, gensym("readagain"), 0); class_addmethod(coll_class, (t_method)coll_writeagain, gensym("writeagain"), 0); class_addmethod(coll_class, (t_method)coll_filetype, gensym("filetype"), A_SYMBOL, 0); class_addmethod(coll_class, (t_method)coll_dump, gensym("dump"), 0); class_addmethod(coll_class, (t_method)coll_open, gensym("open"), 0); class_addmethod(coll_class, (t_method)coll_wclose, gensym("wclose"), 0); class_addmethod(coll_class, (t_method)coll_click, gensym("click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); class_addmethod(coll_class, (t_method)coll_separate, gensym("separate"), A_FLOAT, 0); #ifdef COLL_DEBUG class_addmethod(coll_class, (t_method)coll_debug, gensym("debug"), A_DEFFLOAT, 0); #endif hammerfile_setup(coll_class, 1); collcommon_class = class_new(gensym("coll"), 0, 0, sizeof(t_collcommon), CLASS_PD, 0); /* this call is a nop (collcommon does not embed, and the hammerfile class itself has been already set up above), but it is better to have it around, just in case... */ hammerfile_setup(collcommon_class, 0); int major, minor, bugfix; sys_getversion(&major, &minor, &bugfix); if (major > 0 || minor > 42) logpost(NULL, 4, "this is cyclone/coll %s, %s %d build", CYCLONE_VERSION, CYCLONE_RELEASE, CYCLONE_BUILD); } pd-miXedSon-0.2beta3/hammer/comment.c000066400000000000000000000610641276723360300175200ustar00rootroot00000000000000/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* FIXME creation lag (X-specific) */ /* LATER think about pushing text to the text editor (ctrl-t) -- not easy, because we are not 'textedfor' */ /* LATER think about making the